/*!
 * jQuery JavaScript Library v1.9.1
 * http://jquery.com/
 *
 * Includes Sizzle.js
 * http://sizzlejs.com/
 *
 * Copyright 2005, 2012 jQuery Foundation, Inc. and other contributors
 * Released under the MIT license
 * http://jquery.org/license
 *
 * Date: 2013-2-4
 */
(function(window, undefined) {

	// Can't do this because several apps including ASP.NET trace
	// the stack via arguments.caller.callee and Firefox dies if
	// you try to trace through "use strict" call chains. (#13335)
	// Support: Firefox 18+
	// "use strict";
	var
	// The deferred used on DOM ready
	readyList,

	// A central reference to the root jQuery(document)
	rootjQuery,

	// Support: IE<9
	// For `typeof node.method` instead of `node.method !== undefined`
	core_strundefined = typeof undefined,

	// Use the correct document accordingly with window argument (sandbox)
	document = window.document, location = window.location,

	// Map over jQuery in case of overwrite
	_jQuery = window.jQuery,

	// Map over the $ in case of overwrite
	_$ = window.$,

	// [[Class]] -> type pairs
	class2type = {},

	// List of deleted data cache ids, so we can reuse them
	core_deletedIds = [],

	core_version = "1.9.1",

	// Save a reference to some core methods
	core_concat = core_deletedIds.concat, core_push = core_deletedIds.push, core_slice = core_deletedIds.slice, core_indexOf = core_deletedIds.indexOf, core_toString = class2type.toString, core_hasOwn = class2type.hasOwnProperty, core_trim = core_version.trim,

	// Define a local copy of jQuery
	jQuery = function(selector, context) {
		// The jQuery object is actually just the init constructor 'enhanced'
		return new jQuery.fn.init(selector, context, rootjQuery);
	},

	// Used for matching numbers
	core_pnum = /[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source,

	// Used for splitting on whitespace
	core_rnotwhite = /\S+/g,

	// Make sure we trim BOM and NBSP (here's looking at you, Safari 5.0 and IE)
	rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,

	// A simple way to check for HTML strings
	// Prioritize #id over <tag> to avoid XSS via location.hash (#9521)
	// Strict HTML recognition (#11290: must start with <)
	rquickExpr = /^(?:(<[\w\W]+>)[^>]*|#([\w-]*))$/,

	// Match a standalone tag
	rsingleTag = /^<(\w+)\s*\/?>(?:<\/\1>|)$/,

	// JSON RegExp
	rvalidchars = /^[\],:{}\s]*$/, rvalidbraces = /(?:^|:|,)(?:\s*\[)+/g, rvalidescape = /\\(?:["\\\/bfnrt]|u[\da-fA-F]{4})/g, rvalidtokens = /"[^"\\\r\n]*"|true|false|null|-?(?:\d+\.|)\d+(?:[eE][+-]?\d+|)/g,

	// Matches dashed string for camelizing
	rmsPrefix = /^-ms-/, rdashAlpha = /-([\da-z])/gi,

	// Used by jQuery.camelCase as callback to replace()
	fcamelCase = function(all, letter) {
		return letter.toUpperCase();
	},

	// The ready event handler
	completed = function(event) {

		// readyState === "complete" is good enough for us to call the dom ready
		// in oldIE
		if (document.addEventListener || event.type === "load"
				|| document.readyState === "complete") {
			detach();
			jQuery.ready();
		}
	},
	// Clean-up method for dom ready events
	detach = function() {
		if (document.addEventListener) {
			document.removeEventListener("DOMContentLoaded", completed, false);
			window.removeEventListener("load", completed, false);

		} else {
			document.detachEvent("onreadystatechange", completed);
			window.detachEvent("onload", completed);
		}
	};

	jQuery.fn = jQuery.prototype = {
		// The current version of jQuery being used
		jquery : core_version,

		constructor : jQuery,
		init : function(selector, context, rootjQuery) {
			var match, elem;

			// HANDLE: $(""), $(null), $(undefined), $(false)
			if (!selector) {
				return this;
			}

			// Handle HTML strings
			if (typeof selector === "string") {
				if (selector.charAt(0) === "<"
						&& selector.charAt(selector.length - 1) === ">"
						&& selector.length >= 3) {
					// Assume that strings that start and end with <> are HTML
					// and skip the regex check
					match = [ null, selector, null ];

				} else {
					match = rquickExpr.exec(selector);
				}

				// Match html or make sure no context is specified for #id
				if (match && (match[1] || !context)) {

					// HANDLE: $(html) -> $(array)
					if (match[1]) {
						context = context instanceof jQuery ? context[0]
								: context;

						// scripts is true for back-compat
						jQuery.merge(this, jQuery.parseHTML(match[1], context
								&& context.nodeType ? context.ownerDocument
								|| context : document, true));

						// HANDLE: $(html, props)
						if (rsingleTag.test(match[1])
								&& jQuery.isPlainObject(context)) {
							for (match in context) {
								// Properties of context are called as methods
								// if possible
								if (jQuery.isFunction(this[match])) {
									this[match](context[match]);

									// ...and otherwise set as attributes
								} else {
									this.attr(match, context[match]);
								}
							}
						}

						return this;

						// HANDLE: $(#id)
					} else {
						elem = document.getElementById(match[2]);

						// Check parentNode to catch when Blackberry 4.6 returns
						// nodes that are no longer in the document #6963
						if (elem && elem.parentNode) {
							// Handle the case where IE and Opera return items
							// by name instead of ID
							if (elem.id !== match[2]) {
								return rootjQuery.find(selector);
							}

							// Otherwise, we inject the element directly into
							// the jQuery object
							this.length = 1;
							this[0] = elem;
						}

						this.context = document;
						this.selector = selector;
						return this;
					}

					// HANDLE: $(expr, $(...))
				} else if (!context || context.jquery) {
					return (context || rootjQuery).find(selector);

					// HANDLE: $(expr, context)
					// (which is just equivalent to: $(context).find(expr)
				} else {
					return this.constructor(context).find(selector);
				}

				// HANDLE: $(DOMElement)
			} else if (selector.nodeType) {
				this.context = this[0] = selector;
				this.length = 1;
				return this;

				// HANDLE: $(function)
				// Shortcut for document ready
			} else if (jQuery.isFunction(selector)) {
				return rootjQuery.ready(selector);
			}

			if (selector.selector !== undefined) {
				this.selector = selector.selector;
				this.context = selector.context;
			}

			return jQuery.makeArray(selector, this);
		},

		// Start with an empty selector
		selector : "",

		// The default length of a jQuery object is 0
		length : 0,

		// The number of elements contained in the matched element set
		size : function() {
			return this.length;
		},

		toArray : function() {
			return core_slice.call(this);
		},

		// Get the Nth element in the matched element set OR
		// Get the whole matched element set as a clean array
		get : function(num) {
			return num == null ?

			// Return a 'clean' array
			this.toArray() :

			// Return just the object
			(num < 0 ? this[this.length + num] : this[num]);
		},

		// Take an array of elements and push it onto the stack
		// (returning the new matched element set)
		pushStack : function(elems) {

			// Build a new jQuery matched element set
			var ret = jQuery.merge(this.constructor(), elems);

			// Add the old object onto the stack (as a reference)
			ret.prevObject = this;
			ret.context = this.context;

			// Return the newly-formed element set
			return ret;
		},

		// Execute a callback for every element in the matched set.
		// (You can seed the arguments with an array of args, but this is
		// only used internally.)
		each : function(callback, args) {
			return jQuery.each(this, callback, args);
		},

		ready : function(fn) {
			// Add the callback
			jQuery.ready.promise().done(fn);

			return this;
		},

		slice : function() {
			return this.pushStack(core_slice.apply(this, arguments));
		},

		first : function() {
			return this.eq(0);
		},

		last : function() {
			return this.eq(-1);
		},

		eq : function(i) {
			var len = this.length, j = +i + (i < 0 ? len : 0);
			return this.pushStack(j >= 0 && j < len ? [ this[j] ] : []);
		},

		map : function(callback) {
			return this.pushStack(jQuery.map(this, function(elem, i) {
				return callback.call(elem, i, elem);
			}));
		},

		end : function() {
			return this.prevObject || this.constructor(null);
		},

		// For internal use only.
		// Behaves like an Array's method, not like a jQuery method.
		push : core_push,
		sort : [].sort,
		splice : [].splice
	};

	// Give the init function the jQuery prototype for later instantiation
	jQuery.fn.init.prototype = jQuery.fn;

	jQuery.extend = jQuery.fn.extend = function() {
		var src, copyIsArray, copy, name, options, clone, target = arguments[0]
				|| {}, i = 1, length = arguments.length, deep = false;

		// Handle a deep copy situation
		if (typeof target === "boolean") {
			deep = target;
			target = arguments[1] || {};
			// skip the boolean and the target
			i = 2;
		}

		// Handle case when target is a string or something (possible in deep
		// copy)
		if (typeof target !== "object" && !jQuery.isFunction(target)) {
			target = {};
		}

		// extend jQuery itself if only one argument is passed
		if (length === i) {
			target = this;
			--i;
		}

		for (; i < length; i++) {
			// Only deal with non-null/undefined values
			if ((options = arguments[i]) != null) {
				// Extend the base object
				for (name in options) {
					src = target[name];
					copy = options[name];

					// Prevent never-ending loop
					if (target === copy) {
						continue;
					}

					// Recurse if we're merging plain objects or arrays
					if (deep
							&& copy
							&& (jQuery.isPlainObject(copy) || (copyIsArray = jQuery
									.isArray(copy)))) {
						if (copyIsArray) {
							copyIsArray = false;
							clone = src && jQuery.isArray(src) ? src : [];

						} else {
							clone = src && jQuery.isPlainObject(src) ? src : {};
						}

						// Never move original objects, clone them
						target[name] = jQuery.extend(deep, clone, copy);

						// Don't bring in undefined values
					} else if (copy !== undefined) {
						target[name] = copy;
					}
				}
			}
		}

		// Return the modified object
		return target;
	};

	jQuery
			.extend({
				noConflict : function(deep) {
					if (window.$ === jQuery) {
						window.$ = _$;
					}

					if (deep && window.jQuery === jQuery) {
						window.jQuery = _jQuery;
					}

					return jQuery;
				},

				// Is the DOM ready to be used? Set to true once it occurs.
				isReady : false,

				// A counter to track how many items to wait for before
				// the ready event fires. See #6781
				readyWait : 1,

				// Hold (or release) the ready event
				holdReady : function(hold) {
					if (hold) {
						jQuery.readyWait++;
					} else {
						jQuery.ready(true);
					}
				},

				// Handle when the DOM is ready
				ready : function(wait) {

					// Abort if there are pending holds or we're already ready
					if (wait === true ? --jQuery.readyWait : jQuery.isReady) {
						return;
					}

					// Make sure body exists, at least, in case IE gets a little
					// overzealous (ticket #5443).
					if (!document.body) {
						return setTimeout(jQuery.ready);
					}

					// Remember that the DOM is ready
					jQuery.isReady = true;

					// If a normal DOM Ready event fired, decrement, and wait if
					// need be
					if (wait !== true && --jQuery.readyWait > 0) {
						return;
					}

					// If there are functions bound, to execute
					readyList.resolveWith(document, [ jQuery ]);

					// Trigger any bound ready events
					if (jQuery.fn.trigger) {
						jQuery(document).trigger("ready").off("ready");
					}
				},

				// See test/unit/core.js for details concerning isFunction.
				// Since version 1.3, DOM methods and functions like alert
				// aren't supported. They return false on IE (#2968).
				isFunction : function(obj) {
					return jQuery.type(obj) === "function";
				},

				isArray : Array.isArray || function(obj) {
					return jQuery.type(obj) === "array";
				},

				isWindow : function(obj) {
					return obj != null && obj == obj.window;
				},

				isNumeric : function(obj) {
					return !isNaN(parseFloat(obj)) && isFinite(obj);
				},

				type : function(obj) {
					if (obj == null) {
						return String(obj);
					}
					return typeof obj === "object" || typeof obj === "function" ? class2type[core_toString
							.call(obj)]
							|| "object"
							: typeof obj;
				},

				isPlainObject : function(obj) {
					// Must be an Object.
					// Because of IE, we also have to check the presence of the
					// constructor property.
					// Make sure that DOM nodes and window objects don't pass
					// through, as well
					if (!obj || jQuery.type(obj) !== "object" || obj.nodeType
							|| jQuery.isWindow(obj)) {
						return false;
					}

					try {
						// Not own constructor property must be Object
						if (obj.constructor
								&& !core_hasOwn.call(obj, "constructor")
								&& !core_hasOwn.call(obj.constructor.prototype,
										"isPrototypeOf")) {
							return false;
						}
					} catch (e) {
						// IE8,9 Will throw exceptions on certain host objects
						// #9897
						return false;
					}

					// Own properties are enumerated firstly, so to speed up,
					// if last one is own, then all properties are own.

					var key;
					for (key in obj) {
					}

					return key === undefined || core_hasOwn.call(obj, key);
				},

				isEmptyObject : function(obj) {
					var name;
					for (name in obj) {
						return false;
					}
					return true;
				},

				error : function(msg) {
					throw new Error(msg);
				},

				// data: string of html
				// context (optional): If specified, the fragment will be
				// created in this context, defaults to document
				// keepScripts (optional): If true, will include scripts passed
				// in the html string
				parseHTML : function(data, context, keepScripts) {
					if (!data || typeof data !== "string") {
						return null;
					}
					if (typeof context === "boolean") {
						keepScripts = context;
						context = false;
					}
					context = context || document;

					var parsed = rsingleTag.exec(data), scripts = !keepScripts
							&& [];

					// Single tag
					if (parsed) {
						return [ context.createElement(parsed[1]) ];
					}

					parsed = jQuery.buildFragment([ data ], context, scripts);
					if (scripts) {
						jQuery(scripts).remove();
					}
					return jQuery.merge([], parsed.childNodes);
				},

				parseJSON : function(data) {
					// Attempt to parse using the native JSON parser first
					if (window.JSON && window.JSON.parse) {
						return window.JSON.parse(data);
					}

					if (data === null) {
						return data;
					}

					if (typeof data === "string") {

						// Make sure leading/trailing whitespace is removed (IE
						// can't handle it)
						data = jQuery.trim(data);

						if (data) {
							// Make sure the incoming data is actual JSON
							// Logic borrowed from http://json.org/json2.js
							if (rvalidchars.test(data
									.replace(rvalidescape, "@").replace(
											rvalidtokens, "]").replace(
											rvalidbraces, ""))) {

								return (new Function("return " + data))();
							}
						}
					}

					jQuery.error("Invalid JSON: " + data);
				},

				// Cross-browser xml parsing
				parseXML : function(data) {
					var xml, tmp;
					if (!data || typeof data !== "string") {
						return null;
					}
					try {
						if (window.DOMParser) { // Standard
							tmp = new DOMParser();
							xml = tmp.parseFromString(data, "text/xml");
						} else { // IE
							xml = new ActiveXObject("Microsoft.XMLDOM");
							xml.async = "false";
							xml.loadXML(data);
						}
					} catch (e) {
						xml = undefined;
					}
					if (!xml || !xml.documentElement
							|| xml.getElementsByTagName("parsererror").length) {
						jQuery.error("Invalid XML: " + data);
					}
					return xml;
				},

				noop : function() {
				},

				// Evaluates a script in a global context
				// Workarounds based on findings by Jim Driscoll
				// http://weblogs.java.net/blog/driscoll/archive/2009/09/08/eval-javascript-global-context
				globalEval : function(data) {
					if (data && jQuery.trim(data)) {
						// We use execScript on Internet Explorer
						// We use an anonymous function so that context is
						// window
						// rather than jQuery in Firefox
						(window.execScript || function(data) {
							window["eval"].call(window, data);
						})(data);
					}
				},

				// Convert dashed to camelCase; used by the css and data modules
				// Microsoft forgot to hump their vendor prefix (#9572)
				camelCase : function(string) {
					return string.replace(rmsPrefix, "ms-").replace(rdashAlpha,
							fcamelCase);
				},

				nodeName : function(elem, name) {
					return elem.nodeName
							&& elem.nodeName.toLowerCase() === name
									.toLowerCase();
				},

				// args is for internal usage only
				each : function(obj, callback, args) {
					var value, i = 0, length = obj.length, isArray = isArraylike(obj);

					if (args) {
						if (isArray) {
							for (; i < length; i++) {
								value = callback.apply(obj[i], args);

								if (value === false) {
									break;
								}
							}
						} else {
							for (i in obj) {
								value = callback.apply(obj[i], args);

								if (value === false) {
									break;
								}
							}
						}

						// A special, fast, case for the most common use of each
					} else {
						if (isArray) {
							for (; i < length; i++) {
								value = callback.call(obj[i], i, obj[i]);

								if (value === false) {
									break;
								}
							}
						} else {
							for (i in obj) {
								value = callback.call(obj[i], i, obj[i]);

								if (value === false) {
									break;
								}
							}
						}
					}

					return obj;
				},

				// Use native String.trim function wherever possible
				trim : core_trim && !core_trim.call("\uFEFF\xA0") ? function(
						text) {
					return text == null ? "" : core_trim.call(text);
				} :

				// Otherwise use our own trimming functionality
				function(text) {
					return text == null ? "" : (text + "").replace(rtrim, "");
				},

				// results is for internal usage only
				makeArray : function(arr, results) {
					var ret = results || [];

					if (arr != null) {
						if (isArraylike(Object(arr))) {
							jQuery.merge(ret, typeof arr === "string" ? [ arr ]
									: arr);
						} else {
							core_push.call(ret, arr);
						}
					}

					return ret;
				},

				inArray : function(elem, arr, i) {
					var len;

					if (arr) {
						if (core_indexOf) {
							return core_indexOf.call(arr, elem, i);
						}

						len = arr.length;
						i = i ? i < 0 ? Math.max(0, len + i) : i : 0;

						for (; i < len; i++) {
							// Skip accessing in sparse arrays
							if (i in arr && arr[i] === elem) {
								return i;
							}
						}
					}

					return -1;
				},

				merge : function(first, second) {
					var l = second.length, i = first.length, j = 0;

					if (typeof l === "number") {
						for (; j < l; j++) {
							first[i++] = second[j];
						}
					} else {
						while (second[j] !== undefined) {
							first[i++] = second[j++];
						}
					}

					first.length = i;

					return first;
				},

				grep : function(elems, callback, inv) {
					var retVal, ret = [], i = 0, length = elems.length;
					inv = !!inv;

					// Go through the array, only saving the items
					// that pass the validator function
					for (; i < length; i++) {
						retVal = !!callback(elems[i], i);
						if (inv !== retVal) {
							ret.push(elems[i]);
						}
					}

					return ret;
				},

				// arg is for internal usage only
				map : function(elems, callback, arg) {
					var value, i = 0, length = elems.length, isArray = isArraylike(elems), ret = [];

					// Go through the array, translating each of the items to
					// their
					if (isArray) {
						for (; i < length; i++) {
							value = callback(elems[i], i, arg);

							if (value != null) {
								ret[ret.length] = value;
							}
						}

						// Go through every key on the object,
					} else {
						for (i in elems) {
							value = callback(elems[i], i, arg);

							if (value != null) {
								ret[ret.length] = value;
							}
						}
					}

					// Flatten any nested arrays
					return core_concat.apply([], ret);
				},

				// A global GUID counter for objects
				guid : 1,

				// Bind a function to a context, optionally partially applying
				// any
				// arguments.
				proxy : function(fn, context) {
					var args, proxy, tmp;

					if (typeof context === "string") {
						tmp = fn[context];
						context = fn;
						fn = tmp;
					}

					// Quick check to determine if target is callable, in the
					// spec
					// this throws a TypeError, but we will just return
					// undefined.
					if (!jQuery.isFunction(fn)) {
						return undefined;
					}

					// Simulated bind
					args = core_slice.call(arguments, 2);
					proxy = function() {
						return fn.apply(context || this, args.concat(core_slice
								.call(arguments)));
					};

					// Set the guid of unique handler to the same of original
					// handler, so it can be removed
					proxy.guid = fn.guid = fn.guid || jQuery.guid++;

					return proxy;
				},

				// Multifunctional method to get and set values of a collection
				// The value/s can optionally be executed if it's a function
				access : function(elems, fn, key, value, chainable, emptyGet,
						raw) {
					var i = 0, length = elems.length, bulk = key == null;

					// Sets many values
					if (jQuery.type(key) === "object") {
						chainable = true;
						for (i in key) {
							jQuery.access(elems, fn, i, key[i], true, emptyGet,
									raw);
						}

						// Sets one value
					} else if (value !== undefined) {
						chainable = true;

						if (!jQuery.isFunction(value)) {
							raw = true;
						}

						if (bulk) {
							// Bulk operations run against the entire set
							if (raw) {
								fn.call(elems, value);
								fn = null;

								// ...except when executing function values
							} else {
								bulk = fn;
								fn = function(elem, key, value) {
									return bulk.call(jQuery(elem), value);
								};
							}
						}

						if (fn) {
							for (; i < length; i++) {
								fn(elems[i], key, raw ? value : value.call(
										elems[i], i, fn(elems[i], key)));
							}
						}
					}

					return chainable ? elems :

					// Gets
					bulk ? fn.call(elems) : length ? fn(elems[0], key)
							: emptyGet;
				},

				now : function() {
					return (new Date()).getTime();
				}
			});

	jQuery.ready.promise = function(obj) {
		if (!readyList) {

			readyList = jQuery.Deferred();

			// Catch cases where $(document).ready() is called after the browser
			// event has already occurred.
			// we once tried to use readyState "interactive" here, but it caused
			// issues like the one
			// discovered by ChrisS here:
			// http://bugs.jquery.com/ticket/12282#comment:15
			if (document.readyState === "complete") {
				// Handle it asynchronously to allow scripts the opportunity to
				// delay ready
				setTimeout(jQuery.ready);

				// Standards-based browsers support DOMContentLoaded
			} else if (document.addEventListener) {
				// Use the handy event callback
				document.addEventListener("DOMContentLoaded", completed, false);

				// A fallback to window.onload, that will always work
				window.addEventListener("load", completed, false);

				// If IE event model is used
			} else {
				// Ensure firing before onload, maybe late but safe also for
				// iframes
				document.attachEvent("onreadystatechange", completed);

				// A fallback to window.onload, that will always work
				window.attachEvent("onload", completed);

				// If IE and not a frame
				// continually check to see if the document is ready
				var top = false;

				try {
					top = window.frameElement == null
							&& document.documentElement;
				} catch (e) {
				}

				if (top && top.doScroll) {
					(function doScrollCheck() {
						if (!jQuery.isReady) {

							try {
								// Use the trick by Diego Perini
								// http://javascript.nwbox.com/IEContentLoaded/
								top.doScroll("left");
							} catch (e) {
								return setTimeout(doScrollCheck, 50);
							}

							// detach all dom ready events
							detach();

							// and execute any waiting functions
							jQuery.ready();
						}
					})();
				}
			}
		}
		return readyList.promise(obj);
	};

	// Populate the class2type map
	jQuery.each("Boolean Number String Function Array Date RegExp Object Error"
			.split(" "), function(i, name) {
		class2type["[object " + name + "]"] = name.toLowerCase();
	});

	function isArraylike(obj) {
		var length = obj.length, type = jQuery.type(obj);

		if (jQuery.isWindow(obj)) {
			return false;
		}

		if (obj.nodeType === 1 && length) {
			return true;
		}

		return type === "array"
				|| type !== "function"
				&& (length === 0 || typeof length === "number" && length > 0
						&& (length - 1) in obj);
	}

	// All jQuery objects should point back to these
	rootjQuery = jQuery(document);
	// String to Object options format cache
	var optionsCache = {};

	// Convert String-formatted options into Object-formatted ones and store in
	// cache
	function createOptions(options) {
		var object = optionsCache[options] = {};
		jQuery.each(options.match(core_rnotwhite) || [], function(_, flag) {
			object[flag] = true;
		});
		return object;
	}

	/*
	 * Create a callback list using the following parameters:
	 * 
	 * options: an optional list of space-separated options that will change how
	 * the callback list behaves or a more traditional option object
	 * 
	 * By default a callback list will act like an event callback list and can
	 * be "fired" multiple times.
	 * 
	 * Possible options:
	 * 
	 * once: will ensure the callback list can only be fired once (like a
	 * Deferred)
	 * 
	 * memory: will keep track of previous values and will call any callback
	 * added after the list has been fired right away with the latest
	 * "memorized" values (like a Deferred)
	 * 
	 * unique: will ensure a callback can only be added once (no duplicate in
	 * the list)
	 * 
	 * stopOnFalse: interrupt callings when a callback returns false
	 * 
	 */
	jQuery.Callbacks = function(options) {

		// Convert options from String-formatted to Object-formatted if needed
		// (we check in cache first)
		options = typeof options === "string" ? (optionsCache[options] || createOptions(options))
				: jQuery.extend({}, options);

		var // Flag to know if list is currently firing
		firing,
		// Last fire value (for non-forgettable lists)
		memory,
		// Flag to know if list was already fired
		fired,
		// End of the loop when firing
		firingLength,
		// Index of currently firing callback (modified by remove if needed)
		firingIndex,
		// First callback to fire (used internally by add and fireWith)
		firingStart,
		// Actual callback list
		list = [],
		// Stack of fire calls for repeatable lists
		stack = !options.once && [],
		// Fire callbacks
		fire = function(data) {
			memory = options.memory && data;
			fired = true;
			firingIndex = firingStart || 0;
			firingStart = 0;
			firingLength = list.length;
			firing = true;
			for (; list && firingIndex < firingLength; firingIndex++) {
				if (list[firingIndex].apply(data[0], data[1]) === false
						&& options.stopOnFalse) {
					memory = false; // To prevent further calls using add
					break;
				}
			}
			firing = false;
			if (list) {
				if (stack) {
					if (stack.length) {
						fire(stack.shift());
					}
				} else if (memory) {
					list = [];
				} else {
					self.disable();
				}
			}
		},
		// Actual Callbacks object
		self = {
			// Add a callback or a collection of callbacks to the list
			add : function() {
				if (list) {
					// First, we save the current length
					var start = list.length;
					(function add(args) {
						jQuery.each(args, function(_, arg) {
							var type = jQuery.type(arg);
							if (type === "function") {
								if (!options.unique || !self.has(arg)) {
									list.push(arg);
								}
							} else if (arg && arg.length && type !== "string") {
								// Inspect recursively
								add(arg);
							}
						});
					})(arguments);
					// Do we need to add the callbacks to the
					// current firing batch?
					if (firing) {
						firingLength = list.length;
						// With memory, if we're not firing then
						// we should call right away
					} else if (memory) {
						firingStart = start;
						fire(memory);
					}
				}
				return this;
			},
			// Remove a callback from the list
			remove : function() {
				if (list) {
					jQuery.each(arguments,
							function(_, arg) {
								var index;
								while ((index = jQuery
										.inArray(arg, list, index)) > -1) {
									list.splice(index, 1);
									// Handle firing indexes
									if (firing) {
										if (index <= firingLength) {
											firingLength--;
										}
										if (index <= firingIndex) {
											firingIndex--;
										}
									}
								}
							});
				}
				return this;
			},
			// Check if a given callback is in the list.
			// If no argument is given, return whether or not list has callbacks
			// attached.
			has : function(fn) {
				return fn ? jQuery.inArray(fn, list) > -1
						: !!(list && list.length);
			},
			// Remove all callbacks from the list
			empty : function() {
				list = [];
				return this;
			},
			// Have the list do nothing anymore
			disable : function() {
				list = stack = memory = undefined;
				return this;
			},
			// Is it disabled?
			disabled : function() {
				return !list;
			},
			// Lock the list in its current state
			lock : function() {
				stack = undefined;
				if (!memory) {
					self.disable();
				}
				return this;
			},
			// Is it locked?
			locked : function() {
				return !stack;
			},
			// Call all callbacks with the given context and arguments
			fireWith : function(context, args) {
				args = args || [];
				args = [ context, args.slice ? args.slice() : args ];
				if (list && (!fired || stack)) {
					if (firing) {
						stack.push(args);
					} else {
						fire(args);
					}
				}
				return this;
			},
			// Call all the callbacks with the given arguments
			fire : function() {
				self.fireWith(this, arguments);
				return this;
			},
			// To know if the callbacks have already been called at least once
			fired : function() {
				return !!fired;
			}
		};

		return self;
	};
	jQuery
			.extend({

				Deferred : function(func) {
					var tuples = [
							// action, add listener, listener list, final state
							[ "resolve", "done",
									jQuery.Callbacks("once memory"), "resolved" ],
							[ "reject", "fail",
									jQuery.Callbacks("once memory"), "rejected" ],
							[ "notify", "progress", jQuery.Callbacks("memory") ] ], state = "pending", promise = {
						state : function() {
							return state;
						},
						always : function() {
							deferred.done(arguments).fail(arguments);
							return this;
						},
						then : function( /* fnDone, fnFail, fnProgress */) {
							var fns = arguments;
							return jQuery
									.Deferred(
											function(newDefer) {
												jQuery
														.each(
																tuples,
																function(i,
																		tuple) {
																	var action = tuple[0], fn = jQuery
																			.isFunction(fns[i])
																			&& fns[i];
																	// deferred[
																	// done |
																	// fail |
																	// progress
																	// ] for
																	// forwarding
																	// actions
																	// to
																	// newDefer
																	deferred[tuple[1]]
																			(function() {
																				var returned = fn
																						&& fn
																								.apply(
																										this,
																										arguments);
																				if (returned
																						&& jQuery
																								.isFunction(returned.promise)) {
																					returned
																							.promise()
																							.done(
																									newDefer.resolve)
																							.fail(
																									newDefer.reject)
																							.progress(
																									newDefer.notify);
																				} else {
																					newDefer[action
																							+ "With"]
																							(
																									this === promise ? newDefer
																											.promise()
																											: this,
																									fn ? [ returned ]
																											: arguments);
																				}
																			});
																});
												fns = null;
											}).promise();
						},
						// Get a promise for this deferred
						// If obj is provided, the promise aspect is added to
						// the object
						promise : function(obj) {
							return obj != null ? jQuery.extend(obj, promise)
									: promise;
						}
					}, deferred = {};

					// Keep pipe for back-compat
					promise.pipe = promise.then;

					// Add list-specific methods
					jQuery.each(tuples, function(i, tuple) {
						var list = tuple[2], stateString = tuple[3];

						// promise[ done | fail | progress ] = list.add
						promise[tuple[1]] = list.add;

						// Handle state
						if (stateString) {
							list.add(function() {
								// state = [ resolved | rejected ]
								state = stateString;

								// [ reject_list | resolve_list ].disable;
								// progress_list.lock
							}, tuples[i ^ 1][2].disable, tuples[2][2].lock);
						}

						// deferred[ resolve | reject | notify ]
						deferred[tuple[0]] = function() {
							deferred[tuple[0] + "With"](
									this === deferred ? promise : this,
									arguments);
							return this;
						};
						deferred[tuple[0] + "With"] = list.fireWith;
					});

					// Make the deferred a promise
					promise.promise(deferred);

					// Call given func if any
					if (func) {
						func.call(deferred, deferred);
					}

					// All done!
					return deferred;
				},

				// Deferred helper
				when : function(subordinate /* , ..., subordinateN */) {
					var i = 0, resolveValues = core_slice.call(arguments), length = resolveValues.length,

					// the count of uncompleted subordinates
					remaining = length !== 1
							|| (subordinate && jQuery
									.isFunction(subordinate.promise)) ? length
							: 0,

					// the master Deferred. If resolveValues consist of only a
					// single Deferred, just use that.
					deferred = remaining === 1 ? subordinate : jQuery
							.Deferred(),

					// Update function for both resolve and progress values
					updateFunc = function(i, contexts, values) {
						return function(value) {
							contexts[i] = this;
							values[i] = arguments.length > 1 ? core_slice
									.call(arguments) : value;
							if (values === progressValues) {
								deferred.notifyWith(contexts, values);
							} else if (!(--remaining)) {
								deferred.resolveWith(contexts, values);
							}
						};
					},

					progressValues, progressContexts, resolveContexts;

					// add listeners to Deferred subordinates; treat others as
					// resolved
					if (length > 1) {
						progressValues = new Array(length);
						progressContexts = new Array(length);
						resolveContexts = new Array(length);
						for (; i < length; i++) {
							if (resolveValues[i]
									&& jQuery
											.isFunction(resolveValues[i].promise)) {
								resolveValues[i].promise().done(
										updateFunc(i, resolveContexts,
												resolveValues)).fail(
										deferred.reject).progress(
										updateFunc(i, progressContexts,
												progressValues));
							} else {
								--remaining;
							}
						}
					}

					// if we're not waiting on anything, resolve the master
					if (!remaining) {
						deferred.resolveWith(resolveContexts, resolveValues);
					}

					return deferred.promise();
				}
			});
	jQuery.support = (function() {

		var support, all, a, input, select, fragment, opt, eventName, isSupported, i, div = document
				.createElement("div");

		// Setup
		div.setAttribute("className", "t");
		div.innerHTML = "  <link/><table></table><a href='/a'>a</a><input type='checkbox'/>";

		// Support tests won't run in some limited or non-browser environments
		all = div.getElementsByTagName("*");
		a = div.getElementsByTagName("a")[0];
		if (!all || !a || !all.length) {
			return {};
		}

		// First batch of tests
		select = document.createElement("select");
		opt = select.appendChild(document.createElement("option"));
		input = div.getElementsByTagName("input")[0];

		a.style.cssText = "top:1px;float:left;opacity:.5";
		support = {
			// Test setAttribute on camelCase class. If it works, we need
			// attrFixes when doing get/setAttribute (ie6/7)
			getSetAttribute : div.className !== "t",

			// IE strips leading whitespace when .innerHTML is used
			leadingWhitespace : div.firstChild.nodeType === 3,

			// Make sure that tbody elements aren't automatically inserted
			// IE will insert them into empty tables
			tbody : !div.getElementsByTagName("tbody").length,

			// Make sure that link elements get serialized correctly by
			// innerHTML
			// This requires a wrapper element in IE
			htmlSerialize : !!div.getElementsByTagName("link").length,

			// Get the style information from getAttribute
			// (IE uses .cssText instead)
			style : /top/.test(a.getAttribute("style")),

			// Make sure that URLs aren't manipulated
			// (IE normalizes it by default)
			hrefNormalized : a.getAttribute("href") === "/a",

			// Make sure that element opacity exists
			// (IE uses filter instead)
			// Use a regex to work around a WebKit issue. See #5145
			opacity : /^0.5/.test(a.style.opacity),

			// Verify style float existence
			// (IE uses styleFloat instead of cssFloat)
			cssFloat : !!a.style.cssFloat,

			// Check the default checkbox/radio value ("" on WebKit; "on"
			// elsewhere)
			checkOn : !!input.value,

			// Make sure that a selected-by-default option has a working
			// selected property.
			// (WebKit defaults to false instead of true, IE too, if it's in an
			// optgroup)
			optSelected : opt.selected,

			// Tests for enctype support on a form (#6743)
			enctype : !!document.createElement("form").enctype,

			// Makes sure cloning an html5 element does not cause problems
			// Where outerHTML is undefined, this still works
			html5Clone : document.createElement("nav").cloneNode(true).outerHTML !== "<:nav></:nav>",

			// jQuery.support.boxModel DEPRECATED in 1.8 since we don't support
			// Quirks Mode
			boxModel : document.compatMode === "CSS1Compat",

			// Will be defined later
			deleteExpando : true,
			noCloneEvent : true,
			inlineBlockNeedsLayout : false,
			shrinkWrapBlocks : false,
			reliableMarginRight : true,
			boxSizingReliable : true,
			pixelPosition : false
		};

		// Make sure checked status is properly cloned
		input.checked = true;
		support.noCloneChecked = input.cloneNode(true).checked;

		// Make sure that the options inside disabled selects aren't marked as
		// disabled
		// (WebKit marks them as disabled)
		select.disabled = true;
		support.optDisabled = !opt.disabled;

		// Support: IE<9
		try {
			delete div.test;
		} catch (e) {
			support.deleteExpando = false;
		}

		// Check if we can trust getAttribute("value")
		input = document.createElement("input");
		input.setAttribute("value", "");
		support.input = input.getAttribute("value") === "";

		// Check if an input maintains its value after becoming a radio
		input.value = "t";
		input.setAttribute("type", "radio");
		support.radioValue = input.value === "t";

		// #11217 - WebKit loses check when the name is after the checked
		// attribute
		input.setAttribute("checked", "t");
		input.setAttribute("name", "t");

		fragment = document.createDocumentFragment();
		fragment.appendChild(input);

		// Check if a disconnected checkbox will retain its checked
		// value of true after appended to the DOM (IE6/7)
		support.appendChecked = input.checked;

		// WebKit doesn't clone checked state correctly in fragments
		support.checkClone = fragment.cloneNode(true).cloneNode(true).lastChild.checked;

		// Support: IE<9
		// Opera does not clone events (and typeof div.attachEvent ===
		// undefined).
		// IE9-10 clones events bound via attachEvent, but they don't trigger
		// with .click()
		if (div.attachEvent) {
			div.attachEvent("onclick", function() {
				support.noCloneEvent = false;
			});

			div.cloneNode(true).click();
		}

		// Support: IE<9 (lack submit/change bubble), Firefox 17+ (lack focusin
		// event)
		// Beware of CSP restrictions
		// (https://developer.mozilla.org/en/Security/CSP), test/csp.php
		for (i in {
			submit : true,
			change : true,
			focusin : true
		}) {
			div.setAttribute(eventName = "on" + i, "t");

			support[i + "Bubbles"] = eventName in window
					|| div.attributes[eventName].expando === false;
		}

		div.style.backgroundClip = "content-box";
		div.cloneNode(true).style.backgroundClip = "";
		support.clearCloneStyle = div.style.backgroundClip === "content-box";

		// Run tests that need a body at doc ready
		jQuery(function() {
			var container, marginDiv, tds, divReset = "padding:0;margin:0;border:0;display:block;box-sizing:content-box;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;", body = document
					.getElementsByTagName("body")[0];

			if (!body) {
				// Return for frameset docs that don't have a body
				return;
			}

			container = document.createElement("div");
			container.style.cssText = "border:0;width:0;height:0;position:absolute;top:0;left:-9999px;margin-top:1px";

			body.appendChild(container).appendChild(div);

			// Support: IE8
			// Check if table cells still have offsetWidth/Height when they are
			// set
			// to display:none and there are still other visible table cells in
			// a
			// table row; if so, offsetWidth/Height are not reliable for use
			// when
			// determining if an element has been hidden directly using
			// display:none (it is still safe to use offsets if a parent element
			// is
			// hidden; don safety goggles and see bug #4512 for more
			// information).
			div.innerHTML = "<table><tr><td></td><td>t</td></tr></table>";
			tds = div.getElementsByTagName("td");
			tds[0].style.cssText = "padding:0;margin:0;border:0;display:none";
			isSupported = (tds[0].offsetHeight === 0);

			tds[0].style.display = "";
			tds[1].style.display = "none";

			// Support: IE8
			// Check if empty table cells still have offsetWidth/Height
			support.reliableHiddenOffsets = isSupported
					&& (tds[0].offsetHeight === 0);

			// Check box-sizing and margin behavior
			div.innerHTML = "";
			div.style.cssText = "box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;padding:1px;border:1px;display:block;width:4px;margin-top:1%;position:absolute;top:1%;";
			support.boxSizing = (div.offsetWidth === 4);
			support.doesNotIncludeMarginInBodyOffset = (body.offsetTop !== 1);

			// Use window.getComputedStyle because jsdom on node.js will break
			// without it.
			if (window.getComputedStyle) {
				support.pixelPosition = (window.getComputedStyle(div, null) || {}).top !== "1%";
				support.boxSizingReliable = (window.getComputedStyle(div, null) || {
					width : "4px"
				}).width === "4px";

				// Check if div with explicit width and no margin-right
				// incorrectly
				// gets computed margin-right based on width of container.
				// (#3333)
				// Fails in WebKit before Feb 2011 nightlies
				// WebKit Bug 13343 - getComputedStyle returns wrong value for
				// margin-right
				marginDiv = div.appendChild(document.createElement("div"));
				marginDiv.style.cssText = div.style.cssText = divReset;
				marginDiv.style.marginRight = marginDiv.style.width = "0";
				div.style.width = "1px";

				support.reliableMarginRight = !parseFloat((window
						.getComputedStyle(marginDiv, null) || {}).marginRight);
			}

			if (typeof div.style.zoom !== core_strundefined) {
				// Support: IE<8
				// Check if natively block-level elements act like inline-block
				// elements when setting their display to 'inline' and giving
				// them layout
				div.innerHTML = "";
				div.style.cssText = divReset
						+ "width:1px;padding:1px;display:inline;zoom:1";
				support.inlineBlockNeedsLayout = (div.offsetWidth === 3);

				// Support: IE6
				// Check if elements with layout shrink-wrap their children
				div.style.display = "block";
				div.innerHTML = "<div></div>";
				div.firstChild.style.width = "5px";
				support.shrinkWrapBlocks = (div.offsetWidth !== 3);

				if (support.inlineBlockNeedsLayout) {
					// Prevent IE 6 from affecting layout for positioned
					// elements #11048
					// Prevent IE from shrinking the body in IE 7 mode #12869
					// Support: IE<8
					body.style.zoom = 1;
				}
			}

			body.removeChild(container);

			// Null elements to avoid leaks in IE
			container = div = tds = marginDiv = null;
		});

		// Null elements to avoid leaks in IE
		all = select = fragment = opt = a = input = null;

		return support;
	})();

	var rbrace = /(?:\{[\s\S]*\}|\[[\s\S]*\])$/, rmultiDash = /([A-Z])/g;

	function internalData(elem, name, data, pvt /* Internal Use Only */) {
		if (!jQuery.acceptData(elem)) {
			return;
		}

		var thisCache, ret, internalKey = jQuery.expando, getByName = typeof name === "string",

		// We have to handle DOM nodes and JS objects differently because IE6-7
		// can't GC object references properly across the DOM-JS boundary
		isNode = elem.nodeType,

		// Only DOM nodes need the global jQuery cache; JS object data is
		// attached directly to the object so GC can occur automatically
		cache = isNode ? jQuery.cache : elem,

		// Only defining an ID for JS objects if its cache already exists allows
		// the code to shortcut on the same path as a DOM node with no cache
		id = isNode ? elem[internalKey] : elem[internalKey] && internalKey;

		// Avoid doing any more work than we need to when trying to get data on
		// an
		// object that has no data at all
		if ((!id || !cache[id] || (!pvt && !cache[id].data)) && getByName
				&& data === undefined) {
			return;
		}

		if (!id) {
			// Only DOM nodes need a new unique ID for each element since their
			// data
			// ends up in the global cache
			if (isNode) {
				elem[internalKey] = id = core_deletedIds.pop() || jQuery.guid++;
			} else {
				id = internalKey;
			}
		}

		if (!cache[id]) {
			cache[id] = {};

			// Avoids exposing jQuery metadata on plain JS objects when the
			// object
			// is serialized using JSON.stringify
			if (!isNode) {
				cache[id].toJSON = jQuery.noop;
			}
		}

		// An object can be passed to jQuery.data instead of a key/value pair;
		// this gets
		// shallow copied over onto the existing cache
		if (typeof name === "object" || typeof name === "function") {
			if (pvt) {
				cache[id] = jQuery.extend(cache[id], name);
			} else {
				cache[id].data = jQuery.extend(cache[id].data, name);
			}
		}

		thisCache = cache[id];

		// jQuery data() is stored in a separate object inside the object's
		// internal data
		// cache in order to avoid key collisions between internal data and
		// user-defined
		// data.
		if (!pvt) {
			if (!thisCache.data) {
				thisCache.data = {};
			}

			thisCache = thisCache.data;
		}

		if (data !== undefined) {
			thisCache[jQuery.camelCase(name)] = data;
		}

		// Check for both converted-to-camel and non-converted data property
		// names
		// If a data property was specified
		if (getByName) {

			// First Try to find as-is property data
			ret = thisCache[name];

			// Test for null|undefined property data
			if (ret == null) {

				// Try to find the camelCased property
				ret = thisCache[jQuery.camelCase(name)];
			}
		} else {
			ret = thisCache;
		}

		return ret;
	}

	function internalRemoveData(elem, name, pvt) {
		if (!jQuery.acceptData(elem)) {
			return;
		}

		var i, l, thisCache, isNode = elem.nodeType,

		// See jQuery.data for more information
		cache = isNode ? jQuery.cache : elem, id = isNode ? elem[jQuery.expando]
				: jQuery.expando;

		// If there is already no cache entry for this object, there is no
		// purpose in continuing
		if (!cache[id]) {
			return;
		}

		if (name) {

			thisCache = pvt ? cache[id] : cache[id].data;

			if (thisCache) {

				// Support array or space separated string names for data keys
				if (!jQuery.isArray(name)) {

					// try the string as a key before any manipulation
					if (name in thisCache) {
						name = [ name ];
					} else {

						// split the camel cased version by spaces unless a key
						// with the spaces exists
						name = jQuery.camelCase(name);
						if (name in thisCache) {
							name = [ name ];
						} else {
							name = name.split(" ");
						}
					}
				} else {
					// If "name" is an array of keys...
					// When data is initially created, via ("key", "val")
					// signature,
					// keys will be converted to camelCase.
					// Since there is no way to tell _how_ a key was added,
					// remove
					// both plain key and camelCase key. #12786
					// This will only penalize the array argument path.
					name = name.concat(jQuery.map(name, jQuery.camelCase));
				}

				for (i = 0, l = name.length; i < l; i++) {
					delete thisCache[name[i]];
				}

				// If there is no data left in the cache, we want to continue
				// and let the cache object itself get destroyed
				if (!(pvt ? isEmptyDataObject : jQuery.isEmptyObject)
						(thisCache)) {
					return;
				}
			}
		}

		// See jQuery.data for more information
		if (!pvt) {
			delete cache[id].data;

			// Don't destroy the parent cache unless the internal data object
			// had been the only thing left in it
			if (!isEmptyDataObject(cache[id])) {
				return;
			}
		}

		// Destroy the cache
		if (isNode) {
			jQuery.cleanData([ elem ], true);

			// Use delete when supported for expandos or `cache` is not a window
			// per isWindow (#10080)
		} else if (jQuery.support.deleteExpando || cache != cache.window) {
			delete cache[id];

			// When all else fails, null
		} else {
			cache[id] = null;
		}
	}

	jQuery.extend({
		cache : {},

		// Unique for each copy of jQuery on the page
		// Non-digits removed to match rinlinejQuery
		expando : "jQuery" + (core_version + Math.random()).replace(/\D/g, ""),

		// The following elements throw uncatchable exceptions if you
		// attempt to add expando properties to them.
		noData : {
			"embed" : true,
			// Ban all objects except for Flash (which handle expandos)
			"object" : "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",
			"applet" : true
		},

		hasData : function(elem) {
			elem = elem.nodeType ? jQuery.cache[elem[jQuery.expando]]
					: elem[jQuery.expando];
			return !!elem && !isEmptyDataObject(elem);
		},

		data : function(elem, name, data) {
			return internalData(elem, name, data);
		},

		removeData : function(elem, name) {
			return internalRemoveData(elem, name);
		},

		// For internal use only.
		_data : function(elem, name, data) {
			return internalData(elem, name, data, true);
		},

		_removeData : function(elem, name) {
			return internalRemoveData(elem, name, true);
		},

		// A method for determining if a DOM node can handle the data expando
		acceptData : function(elem) {
			// Do not set data on non-element because it will not be cleared
			// (#8335).
			if (elem.nodeType && elem.nodeType !== 1 && elem.nodeType !== 9) {
				return false;
			}

			var noData = elem.nodeName
					&& jQuery.noData[elem.nodeName.toLowerCase()];

			// nodes accept data unless otherwise specified; rejection can be
			// conditional
			return !noData || noData !== true
					&& elem.getAttribute("classid") === noData;
		}
	});

	jQuery.fn.extend({
		data : function(key, value) {
			var attrs, name, elem = this[0], i = 0, data = null;

			// Gets all values
			if (key === undefined) {
				if (this.length) {
					data = jQuery.data(elem);

					if (elem.nodeType === 1
							&& !jQuery._data(elem, "parsedAttrs")) {
						attrs = elem.attributes;
						for (; i < attrs.length; i++) {
							name = attrs[i].name;

							if (!name.indexOf("data-")) {
								name = jQuery.camelCase(name.slice(5));

								dataAttr(elem, name, data[name]);
							}
						}
						jQuery._data(elem, "parsedAttrs", true);
					}
				}

				return data;
			}

			// Sets multiple values
			if (typeof key === "object") {
				return this.each(function() {
					jQuery.data(this, key);
				});
			}

			return jQuery.access(this, function(value) {

				if (value === undefined) {
					// Try to fetch any internally stored data first
					return elem ? dataAttr(elem, key, jQuery.data(elem, key))
							: null;
				}

				this.each(function() {
					jQuery.data(this, key, value);
				});
			}, null, value, arguments.length > 1, null, true);
		},

		removeData : function(key) {
			return this.each(function() {
				jQuery.removeData(this, key);
			});
		}
	});

	function dataAttr(elem, key, data) {
		// If nothing was found internally, try to fetch any
		// data from the HTML5 data-* attribute
		if (data === undefined && elem.nodeType === 1) {

			var name = "data-" + key.replace(rmultiDash, "-$1").toLowerCase();

			data = elem.getAttribute(name);

			if (typeof data === "string") {
				try {
					data = data === "true" ? true : data === "false" ? false
							: data === "null" ? null :
							// Only convert to a number if it doesn't change the
							// string
							+data + "" === data ? +data
									: rbrace.test(data) ? jQuery
											.parseJSON(data) : data;
				} catch (e) {
				}

				// Make sure we set the data so it isn't changed later
				jQuery.data(elem, key, data);

			} else {
				data = undefined;
			}
		}

		return data;
	}

	// checks a cache object for emptiness
	function isEmptyDataObject(obj) {
		var name;
		for (name in obj) {

			// if the public data object is empty, the private is still empty
			if (name === "data" && jQuery.isEmptyObject(obj[name])) {
				continue;
			}
			if (name !== "toJSON") {
				return false;
			}
		}

		return true;
	}
	jQuery
			.extend({
				queue : function(elem, type, data) {
					var queue;

					if (elem) {
						type = (type || "fx") + "queue";
						queue = jQuery._data(elem, type);

						// Speed up dequeue by getting out quickly if this is
						// just a lookup
						if (data) {
							if (!queue || jQuery.isArray(data)) {
								queue = jQuery._data(elem, type, jQuery
										.makeArray(data));
							} else {
								queue.push(data);
							}
						}
						return queue || [];
					}
				},

				dequeue : function(elem, type) {
					type = type || "fx";

					var queue = jQuery.queue(elem, type), startLength = queue.length, fn = queue
							.shift(), hooks = jQuery._queueHooks(elem, type), next = function() {
						jQuery.dequeue(elem, type);
					};

					// If the fx queue is dequeued, always remove the progress
					// sentinel
					if (fn === "inprogress") {
						fn = queue.shift();
						startLength--;
					}

					hooks.cur = fn;
					if (fn) {

						// Add a progress sentinel to prevent the fx queue from
						// being
						// automatically dequeued
						if (type === "fx") {
							queue.unshift("inprogress");
						}

						// clear up the last queue stop function
						delete hooks.stop;
						fn.call(elem, next, hooks);
					}

					if (!startLength && hooks) {
						hooks.empty.fire();
					}
				},

				// not intended for public consumption - generates a queueHooks
				// object, or returns the current one
				_queueHooks : function(elem, type) {
					var key = type + "queueHooks";
					return jQuery._data(elem, key) || jQuery._data(elem, key, {
						empty : jQuery.Callbacks("once memory").add(function() {
							jQuery._removeData(elem, type + "queue");
							jQuery._removeData(elem, key);
						})
					});
				}
			});

	jQuery.fn
			.extend({
				queue : function(type, data) {
					var setter = 2;

					if (typeof type !== "string") {
						data = type;
						type = "fx";
						setter--;
					}

					if (arguments.length < setter) {
						return jQuery.queue(this[0], type);
					}

					return data === undefined ? this : this.each(function() {
						var queue = jQuery.queue(this, type, data);

						// ensure a hooks for this queue
						jQuery._queueHooks(this, type);

						if (type === "fx" && queue[0] !== "inprogress") {
							jQuery.dequeue(this, type);
						}
					});
				},
				dequeue : function(type) {
					return this.each(function() {
						jQuery.dequeue(this, type);
					});
				},
				// Based off of the plugin by Clint Helfers, with permission.
				// http://blindsignals.com/index.php/2009/07/jquery-delay/
				delay : function(time, type) {
					time = jQuery.fx ? jQuery.fx.speeds[time] || time : time;
					type = type || "fx";

					return this.queue(type, function(next, hooks) {
						var timeout = setTimeout(next, time);
						hooks.stop = function() {
							clearTimeout(timeout);
						};
					});
				},
				clearQueue : function(type) {
					return this.queue(type || "fx", []);
				},
				// Get a promise resolved when queues of a certain type
				// are emptied (fx is the type by default)
				promise : function(type, obj) {
					var tmp, count = 1, defer = jQuery.Deferred(), elements = this, i = this.length, resolve = function() {
						if (!(--count)) {
							defer.resolveWith(elements, [ elements ]);
						}
					};

					if (typeof type !== "string") {
						obj = type;
						type = undefined;
					}
					type = type || "fx";

					while (i--) {
						tmp = jQuery._data(elements[i], type + "queueHooks");
						if (tmp && tmp.empty) {
							count++;
							tmp.empty.add(resolve);
						}
					}
					resolve();
					return defer.promise(obj);
				}
			});
	var nodeHook, boolHook, rclass = /[\t\r\n]/g, rreturn = /\r/g, rfocusable = /^(?:input|select|textarea|button|object)$/i, rclickable = /^(?:a|area)$/i, rboolean = /^(?:checked|selected|autofocus|autoplay|async|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped)$/i, ruseDefault = /^(?:checked|selected)$/i, getSetAttribute = jQuery.support.getSetAttribute, getSetInput = jQuery.support.input;

	jQuery.fn
			.extend({
				attr : function(name, value) {
					return jQuery.access(this, jQuery.attr, name, value,
							arguments.length > 1);
				},

				removeAttr : function(name) {
					return this.each(function() {
						jQuery.removeAttr(this, name);
					});
				},

				prop : function(name, value) {
					return jQuery.access(this, jQuery.prop, name, value,
							arguments.length > 1);
				},

				removeProp : function(name) {
					name = jQuery.propFix[name] || name;
					return this.each(function() {
						// try/catch handles cases where IE balks (such as
						// removing a property on window)
						try {
							this[name] = undefined;
							delete this[name];
						} catch (e) {
						}
					});
				},

				addClass : function(value) {
					var classes, elem, cur, clazz, j, i = 0, len = this.length, proceed = typeof value === "string"
							&& value;

					if (jQuery.isFunction(value)) {
						return this.each(function(j) {
							jQuery(this).addClass(
									value.call(this, j, this.className));
						});
					}

					if (proceed) {
						// The disjunction here is for better compressibility
						// (see removeClass)
						classes = (value || "").match(core_rnotwhite) || [];

						for (; i < len; i++) {
							elem = this[i];
							cur = elem.nodeType === 1
									&& (elem.className ? (" " + elem.className + " ")
											.replace(rclass, " ")
											: " ");

							if (cur) {
								j = 0;
								while ((clazz = classes[j++])) {
									if (cur.indexOf(" " + clazz + " ") < 0) {
										cur += clazz + " ";
									}
								}
								elem.className = jQuery.trim(cur);

							}
						}
					}

					return this;
				},

				removeClass : function(value) {
					var classes, elem, cur, clazz, j, i = 0, len = this.length, proceed = arguments.length === 0
							|| typeof value === "string" && value;

					if (jQuery.isFunction(value)) {
						return this.each(function(j) {
							jQuery(this).removeClass(
									value.call(this, j, this.className));
						});
					}
					if (proceed) {
						classes = (value || "").match(core_rnotwhite) || [];

						for (; i < len; i++) {
							elem = this[i];
							// This expression is here for better
							// compressibility (see addClass)
							cur = elem.nodeType === 1
									&& (elem.className ? (" " + elem.className + " ")
											.replace(rclass, " ")
											: "");

							if (cur) {
								j = 0;
								while ((clazz = classes[j++])) {
									// Remove *all* instances
									while (cur.indexOf(" " + clazz + " ") >= 0) {
										cur = cur.replace(" " + clazz + " ",
												" ");
									}
								}
								elem.className = value ? jQuery.trim(cur) : "";
							}
						}
					}

					return this;
				},

				toggleClass : function(value, stateVal) {
					var type = typeof value, isBool = typeof stateVal === "boolean";

					if (jQuery.isFunction(value)) {
						return this.each(function(i) {
							jQuery(this).toggleClass(
									value.call(this, i, this.className,
											stateVal), stateVal);
						});
					}

					return this
							.each(function() {
								if (type === "string") {
									// toggle individual class names
									var className, i = 0, self = jQuery(this), state = stateVal, classNames = value
											.match(core_rnotwhite)
											|| [];

									while ((className = classNames[i++])) {
										// check each className given, space
										// separated list
										state = isBool ? state : !self
												.hasClass(className);
										self[state ? "addClass" : "removeClass"]
												(className);
									}

									// Toggle whole class name
								} else if (type === core_strundefined
										|| type === "boolean") {
									if (this.className) {
										// store className if set
										jQuery._data(this, "__className__",
												this.className);
									}

									// If the element has a class name or if
									// we're passed "false",
									// then remove the whole classname (if there
									// was one, the above saved it).
									// Otherwise bring back whatever was
									// previously saved (if anything),
									// falling back to the empty string if
									// nothing was stored.
									this.className = this.className
											|| value === false ? "" : jQuery
											._data(this, "__className__")
											|| "";
								}
							});
				},

				hasClass : function(selector) {
					var className = " " + selector + " ", i = 0, l = this.length;
					for (; i < l; i++) {
						if (this[i].nodeType === 1
								&& (" " + this[i].className + " ").replace(
										rclass, " ").indexOf(className) >= 0) {
							return true;
						}
					}

					return false;
				},

				val : function(value) {
					var ret, hooks, isFunction, elem = this[0];

					if (!arguments.length) {
						if (elem) {
							hooks = jQuery.valHooks[elem.type]
									|| jQuery.valHooks[elem.nodeName
											.toLowerCase()];

							if (hooks
									&& "get" in hooks
									&& (ret = hooks.get(elem, "value")) !== undefined) {
								return ret;
							}

							ret = elem.value;

							return typeof ret === "string" ?
							// handle most common string cases
							ret.replace(rreturn, "") :
							// handle cases where value is null/undef or number
							ret == null ? "" : ret;
						}

						return;
					}

					isFunction = jQuery.isFunction(value);

					return this
							.each(function(i) {
								var val, self = jQuery(this);

								if (this.nodeType !== 1) {
									return;
								}

								if (isFunction) {
									val = value.call(this, i, self.val());
								} else {
									val = value;
								}

								// Treat null/undefined as ""; convert numbers
								// to string
								if (val == null) {
									val = "";
								} else if (typeof val === "number") {
									val += "";
								} else if (jQuery.isArray(val)) {
									val = jQuery.map(val, function(value) {
										return value == null ? "" : value + "";
									});
								}

								hooks = jQuery.valHooks[this.type]
										|| jQuery.valHooks[this.nodeName
												.toLowerCase()];

								// If set returns undefined, fall back to normal
								// setting
								if (!hooks
										|| !("set" in hooks)
										|| hooks.set(this, val, "value") === undefined) {
									this.value = val;
								}
							});
				}
			});

	jQuery
			.extend({
				valHooks : {
					option : {
						get : function(elem) {
							// attributes.value is undefined in Blackberry 4.7
							// but
							// uses .value. See #6932
							var val = elem.attributes.value;
							return !val || val.specified ? elem.value
									: elem.text;
						}
					},
					select : {
						get : function(elem) {
							var value, option, options = elem.options, index = elem.selectedIndex, one = elem.type === "select-one"
									|| index < 0, values = one ? null : [], max = one ? index + 1
									: options.length, i = index < 0 ? max
									: one ? index : 0;

							// Loop through all the selected options
							for (; i < max; i++) {
								option = options[i];

								// oldIE doesn't update selected after form
								// reset (#2551)
								if ((option.selected || i === index)
										&&
										// Don't return options that are
										// disabled or in a disabled optgroup
										(jQuery.support.optDisabled ? !option.disabled
												: option
														.getAttribute("disabled") === null)
										&& (!option.parentNode.disabled || !jQuery
												.nodeName(option.parentNode,
														"optgroup"))) {

									// Get the specific value for the option
									value = jQuery(option).val();

									// We don't need an array for one selects
									if (one) {
										return value;
									}

									// Multi-Selects return an array
									values.push(value);
								}
							}

							return values;
						},

						set : function(elem, value) {
							var values = jQuery.makeArray(value);

							jQuery(elem).find("option").each(
									function() {
										this.selected = jQuery.inArray(jQuery(
												this).val(), values) >= 0;
									});

							if (!values.length) {
								elem.selectedIndex = -1;
							}
							return values;
						}
					}
				},

				attr : function(elem, name, value) {
					var hooks, notxml, ret, nType = elem.nodeType;

					// don't get/set attributes on text, comment and attribute
					// nodes
					if (!elem || nType === 3 || nType === 8 || nType === 2) {
						return;
					}

					// Fallback to prop when attributes are not supported
					if (typeof elem.getAttribute === core_strundefined) {
						return jQuery.prop(elem, name, value);
					}

					notxml = nType !== 1 || !jQuery.isXMLDoc(elem);

					// All attributes are lowercase
					// Grab necessary hook if one is defined
					if (notxml) {
						name = name.toLowerCase();
						hooks = jQuery.attrHooks[name]
								|| (rboolean.test(name) ? boolHook : nodeHook);
					}

					if (value !== undefined) {

						if (value === null) {
							jQuery.removeAttr(elem, name);

						} else if (hooks
								&& notxml
								&& "set" in hooks
								&& (ret = hooks.set(elem, value, name)) !== undefined) {
							return ret;

						} else {
							elem.setAttribute(name, value + "");
							return value;
						}

					} else if (hooks && notxml && "get" in hooks
							&& (ret = hooks.get(elem, name)) !== null) {
						return ret;

					} else {

						// In IE9+, Flash objects don't have .getAttribute
						// (#12945)
						// Support: IE9+
						if (typeof elem.getAttribute !== core_strundefined) {
							ret = elem.getAttribute(name);
						}

						// Non-existent attributes return null, we normalize to
						// undefined
						return ret == null ? undefined : ret;
					}
				},

				removeAttr : function(elem, value) {
					var name, propName, i = 0, attrNames = value
							&& value.match(core_rnotwhite);

					if (attrNames && elem.nodeType === 1) {
						while ((name = attrNames[i++])) {
							propName = jQuery.propFix[name] || name;

							// Boolean attributes get special treatment (#10870)
							if (rboolean.test(name)) {
								// Set corresponding property to false for
								// boolean attributes
								// Also clear defaultChecked/defaultSelected (if
								// appropriate) for IE<8
								if (!getSetAttribute && ruseDefault.test(name)) {
									elem[jQuery.camelCase("default-" + name)] = elem[propName] = false;
								} else {
									elem[propName] = false;
								}

								// See #9699 for explanation of this approach
								// (setting first, then removal)
							} else {
								jQuery.attr(elem, name, "");
							}

							elem.removeAttribute(getSetAttribute ? name
									: propName);
						}
					}
				},

				attrHooks : {
					type : {
						set : function(elem, value) {
							if (!jQuery.support.radioValue && value === "radio"
									&& jQuery.nodeName(elem, "input")) {
								// Setting the type on a radio button after the
								// value resets the value in IE6-9
								// Reset value to default in case type is set
								// after value during creation
								var val = elem.value;
								elem.setAttribute("type", value);
								if (val) {
									elem.value = val;
								}
								return value;
							}
						}
					}
				},

				propFix : {
					tabindex : "tabIndex",
					readonly : "readOnly",
					"for" : "htmlFor",
					"class" : "className",
					maxlength : "maxLength",
					cellspacing : "cellSpacing",
					cellpadding : "cellPadding",
					rowspan : "rowSpan",
					colspan : "colSpan",
					usemap : "useMap",
					frameborder : "frameBorder",
					contenteditable : "contentEditable"
				},

				prop : function(elem, name, value) {
					var ret, hooks, notxml, nType = elem.nodeType;

					// don't get/set properties on text, comment and attribute
					// nodes
					if (!elem || nType === 3 || nType === 8 || nType === 2) {
						return;
					}

					notxml = nType !== 1 || !jQuery.isXMLDoc(elem);

					if (notxml) {
						// Fix name and attach hooks
						name = jQuery.propFix[name] || name;
						hooks = jQuery.propHooks[name];
					}

					if (value !== undefined) {
						if (hooks
								&& "set" in hooks
								&& (ret = hooks.set(elem, value, name)) !== undefined) {
							return ret;

						} else {
							return (elem[name] = value);
						}

					} else {
						if (hooks && "get" in hooks
								&& (ret = hooks.get(elem, name)) !== null) {
							return ret;

						} else {
							return elem[name];
						}
					}
				},

				propHooks : {
					tabIndex : {
						get : function(elem) {
							// elem.tabIndex doesn't always return the correct
							// value when it hasn't been explicitly set
							// http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/
							var attributeNode = elem
									.getAttributeNode("tabindex");

							return attributeNode && attributeNode.specified ? parseInt(
									attributeNode.value, 10)
									: rfocusable.test(elem.nodeName)
											|| rclickable.test(elem.nodeName)
											&& elem.href ? 0 : undefined;
						}
					}
				}
			});

	// Hook for boolean attributes
	boolHook = {
		get : function(elem, name) {
			var
			// Use .prop to determine if this attribute is understood as boolean
			prop = jQuery.prop(elem, name),

			// Fetch it accordingly
			attr = typeof prop === "boolean" && elem.getAttribute(name), detail = typeof prop === "boolean" ?

			getSetInput && getSetAttribute ? attr != null :
			// oldIE fabricates an empty string for missing boolean attributes
			// and conflates checked/selected into attroperties
			ruseDefault.test(name) ? elem[jQuery.camelCase("default-" + name)]
					: !!attr
					:

					// fetch an attribute node for properties not recognized as
					// boolean
					elem.getAttributeNode(name);

			return detail && detail.value !== false ? name.toLowerCase()
					: undefined;
		},
		set : function(elem, value, name) {
			if (value === false) {
				// Remove boolean attributes when set to false
				jQuery.removeAttr(elem, name);
			} else if (getSetInput && getSetAttribute
					|| !ruseDefault.test(name)) {
				// IE<8 needs the *property* name
				elem.setAttribute(!getSetAttribute && jQuery.propFix[name]
						|| name, name);

				// Use defaultChecked and defaultSelected for oldIE
			} else {
				elem[jQuery.camelCase("default-" + name)] = elem[name] = true;
			}

			return name;
		}
	};

	// fix oldIE value attroperty
	if (!getSetInput || !getSetAttribute) {
		jQuery.attrHooks.value = {
			get : function(elem, name) {
				var ret = elem.getAttributeNode(name);
				return jQuery.nodeName(elem, "input") ?

				// Ignore the value *property* by using defaultValue
				elem.defaultValue :

				ret && ret.specified ? ret.value : undefined;
			},
			set : function(elem, value, name) {
				if (jQuery.nodeName(elem, "input")) {
					// Does not return so that setAttribute is also used
					elem.defaultValue = value;
				} else {
					// Use nodeHook if defined (#1954); otherwise setAttribute
					// is fine
					return nodeHook && nodeHook.set(elem, value, name);
				}
			}
		};
	}

	// IE6/7 do not support getting/setting some attributes with
	// get/setAttribute
	if (!getSetAttribute) {

		// Use this for any attribute in IE6/7
		// This fixes almost every IE6/7 issue
		nodeHook = jQuery.valHooks.button = {
			get : function(elem, name) {
				var ret = elem.getAttributeNode(name);
				return ret
						&& (name === "id" || name === "name"
								|| name === "coords" ? ret.value !== ""
								: ret.specified) ? ret.value : undefined;
			},
			set : function(elem, value, name) {
				// Set the existing or create a new attribute node
				var ret = elem.getAttributeNode(name);
				if (!ret) {
					elem.setAttributeNode((ret = elem.ownerDocument
							.createAttribute(name)));
				}

				ret.value = value += "";

				// Break association with cloned elements by also using
				// setAttribute (#9646)
				return name === "value" || value === elem.getAttribute(name) ? value
						: undefined;
			}
		};

		// Set contenteditable to false on removals(#10429)
		// Setting to empty string throws an error as an invalid value
		jQuery.attrHooks.contenteditable = {
			get : nodeHook.get,
			set : function(elem, value, name) {
				nodeHook.set(elem, value === "" ? false : value, name);
			}
		};

		// Set width and height to auto instead of 0 on empty string( Bug #8150
		// )
		// This is for removals
		jQuery.each([ "width", "height" ], function(i, name) {
			jQuery.attrHooks[name] = jQuery.extend(jQuery.attrHooks[name], {
				set : function(elem, value) {
					if (value === "") {
						elem.setAttribute(name, "auto");
						return value;
					}
				}
			});
		});
	}

	// Some attributes require a special call on IE
	// http://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx
	if (!jQuery.support.hrefNormalized) {
		jQuery.each([ "href", "src", "width", "height" ], function(i, name) {
			jQuery.attrHooks[name] = jQuery.extend(jQuery.attrHooks[name], {
				get : function(elem) {
					var ret = elem.getAttribute(name, 2);
					return ret == null ? undefined : ret;
				}
			});
		});

		// href/src property should get the full normalized URL (#10299/#12915)
		jQuery.each([ "href", "src" ], function(i, name) {
			jQuery.propHooks[name] = {
				get : function(elem) {
					return elem.getAttribute(name, 4);
				}
			};
		});
	}

	if (!jQuery.support.style) {
		jQuery.attrHooks.style = {
			get : function(elem) {
				// Return undefined in the case of empty string
				// Note: IE uppercases css property names, but if we were to
				// .toLowerCase()
				// .cssText, that would destroy case senstitivity in URL's, like
				// in "background"
				return elem.style.cssText || undefined;
			},
			set : function(elem, value) {
				return (elem.style.cssText = value + "");
			}
		};
	}

	// Safari mis-reports the default selected property of an option
	// Accessing the parent's selectedIndex property fixes it
	if (!jQuery.support.optSelected) {
		jQuery.propHooks.selected = jQuery.extend(jQuery.propHooks.selected, {
			get : function(elem) {
				var parent = elem.parentNode;

				if (parent) {
					parent.selectedIndex;

					// Make sure that it also works with optgroups, see #5701
					if (parent.parentNode) {
						parent.parentNode.selectedIndex;
					}
				}
				return null;
			}
		});
	}

	// IE6/7 call enctype encoding
	if (!jQuery.support.enctype) {
		jQuery.propFix.enctype = "encoding";
	}

	// Radios and checkboxes getter/setter
	if (!jQuery.support.checkOn) {
		jQuery.each([ "radio", "checkbox" ], function() {
			jQuery.valHooks[this] = {
				get : function(elem) {
					// Handle the case where in Webkit "" is returned instead of
					// "on" if a value isn't specified
					return elem.getAttribute("value") === null ? "on"
							: elem.value;
				}
			};
		});
	}
	jQuery.each([ "radio", "checkbox" ], function() {
		jQuery.valHooks[this] = jQuery.extend(jQuery.valHooks[this], {
			set : function(elem, value) {
				if (jQuery.isArray(value)) {
					return (elem.checked = jQuery.inArray(jQuery(elem).val(),
							value) >= 0);
				}
			}
		});
	});
	var rformElems = /^(?:input|select|textarea)$/i, rkeyEvent = /^key/, rmouseEvent = /^(?:mouse|contextmenu)|click/, rfocusMorph = /^(?:focusinfocus|focusoutblur)$/, rtypenamespace = /^([^.]*)(?:\.(.+)|)$/;

	function returnTrue() {
		return true;
	}

	function returnFalse() {
		return false;
	}

	/*
	 * Helper functions for managing events -- not part of the public interface.
	 * Props to Dean Edwards' addEvent library for many of the ideas.
	 */
	jQuery.event = {

		global : {},

		add : function(elem, types, handler, data, selector) {
			var tmp, events, t, handleObjIn, special, eventHandle, handleObj, handlers, type, namespaces, origType, elemData = jQuery
					._data(elem);

			// Don't attach events to noData or text/comment nodes (but allow
			// plain objects)
			if (!elemData) {
				return;
			}

			// Caller can pass in an object of custom data in lieu of the
			// handler
			if (handler.handler) {
				handleObjIn = handler;
				handler = handleObjIn.handler;
				selector = handleObjIn.selector;
			}

			// Make sure that the handler has a unique ID, used to find/remove
			// it later
			if (!handler.guid) {
				handler.guid = jQuery.guid++;
			}

			// Init the element's event structure and main handler, if this is
			// the first
			if (!(events = elemData.events)) {
				events = elemData.events = {};
			}
			if (!(eventHandle = elemData.handle)) {
				eventHandle = elemData.handle = function(e) {
					// Discard the second event of a jQuery.event.trigger() and
					// when an event is called after a page has unloaded
					return typeof jQuery !== core_strundefined
							&& (!e || jQuery.event.triggered !== e.type) ? jQuery.event.dispatch
							.apply(eventHandle.elem, arguments)
							: undefined;
				};
				// Add elem as a property of the handle fn to prevent a memory
				// leak with IE non-native events
				eventHandle.elem = elem;
			}

			// Handle multiple events separated by a space
			// jQuery(...).bind("mouseover mouseout", fn);
			types = (types || "").match(core_rnotwhite) || [ "" ];
			t = types.length;
			while (t--) {
				tmp = rtypenamespace.exec(types[t]) || [];
				type = origType = tmp[1];
				namespaces = (tmp[2] || "").split(".").sort();

				// If event changes its type, use the special event handlers for
				// the changed type
				special = jQuery.event.special[type] || {};

				// If selector defined, determine special event api type,
				// otherwise given type
				type = (selector ? special.delegateType : special.bindType)
						|| type;

				// Update special based on newly reset type
				special = jQuery.event.special[type] || {};

				// handleObj is passed to all event handlers
				handleObj = jQuery.extend({
					type : type,
					origType : origType,
					data : data,
					handler : handler,
					guid : handler.guid,
					selector : selector,
					needsContext : selector
							&& jQuery.expr.match.needsContext.test(selector),
					namespace : namespaces.join(".")
				}, handleObjIn);

				// Init the event handler queue if we're the first
				if (!(handlers = events[type])) {
					handlers = events[type] = [];
					handlers.delegateCount = 0;

					// Only use addEventListener/attachEvent if the special
					// events handler returns false
					if (!special.setup
							|| special.setup.call(elem, data, namespaces,
									eventHandle) === false) {
						// Bind the global event handler to the element
						if (elem.addEventListener) {
							elem.addEventListener(type, eventHandle, false);

						} else if (elem.attachEvent) {
							elem.attachEvent("on" + type, eventHandle);
						}
					}
				}

				if (special.add) {
					special.add.call(elem, handleObj);

					if (!handleObj.handler.guid) {
						handleObj.handler.guid = handler.guid;
					}
				}

				// Add to the element's handler list, delegates in front
				if (selector) {
					handlers.splice(handlers.delegateCount++, 0, handleObj);
				} else {
					handlers.push(handleObj);
				}

				// Keep track of which events have ever been used, for event
				// optimization
				jQuery.event.global[type] = true;
			}

			// Nullify elem to prevent memory leaks in IE
			elem = null;
		},

		// Detach an event or set of events from an element
		remove : function(elem, types, handler, selector, mappedTypes) {
			var j, handleObj, tmp, origCount, t, events, special, handlers, type, namespaces, origType, elemData = jQuery
					.hasData(elem)
					&& jQuery._data(elem);

			if (!elemData || !(events = elemData.events)) {
				return;
			}

			// Once for each type.namespace in types; type may be omitted
			types = (types || "").match(core_rnotwhite) || [ "" ];
			t = types.length;
			while (t--) {
				tmp = rtypenamespace.exec(types[t]) || [];
				type = origType = tmp[1];
				namespaces = (tmp[2] || "").split(".").sort();

				// Unbind all events (on this namespace, if provided) for the
				// element
				if (!type) {
					for (type in events) {
						jQuery.event.remove(elem, type + types[t], handler,
								selector, true);
					}
					continue;
				}

				special = jQuery.event.special[type] || {};
				type = (selector ? special.delegateType : special.bindType)
						|| type;
				handlers = events[type] || [];
				tmp = tmp[2]
						&& new RegExp("(^|\\.)"
								+ namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)");

				// Remove matching events
				origCount = j = handlers.length;
				while (j--) {
					handleObj = handlers[j];

					if ((mappedTypes || origType === handleObj.origType)
							&& (!handler || handler.guid === handleObj.guid)
							&& (!tmp || tmp.test(handleObj.namespace))
							&& (!selector || selector === handleObj.selector || selector === "**"
									&& handleObj.selector)) {
						handlers.splice(j, 1);

						if (handleObj.selector) {
							handlers.delegateCount--;
						}
						if (special.remove) {
							special.remove.call(elem, handleObj);
						}
					}
				}

				// Remove generic event handler if we removed something and no
				// more handlers exist
				// (avoids potential for endless recursion during removal of
				// special event handlers)
				if (origCount && !handlers.length) {
					if (!special.teardown
							|| special.teardown.call(elem, namespaces,
									elemData.handle) === false) {
						jQuery.removeEvent(elem, type, elemData.handle);
					}

					delete events[type];
				}
			}

			// Remove the expando if it's no longer used
			if (jQuery.isEmptyObject(events)) {
				delete elemData.handle;

				// removeData also checks for emptiness and clears the expando
				// if empty
				// so use it instead of delete
				jQuery._removeData(elem, "events");
			}
		},

		trigger : function(event, data, elem, onlyHandlers) {
			var handle, ontype, cur, bubbleType, special, tmp, i, eventPath = [ elem
					|| document ], type = core_hasOwn.call(event, "type") ? event.type
					: event, namespaces = core_hasOwn.call(event, "namespace") ? event.namespace
					.split(".")
					: [];

			cur = tmp = elem = elem || document;

			// Don't do events on text and comment nodes
			if (elem.nodeType === 3 || elem.nodeType === 8) {
				return;
			}

			// focus/blur morphs to focusin/out; ensure we're not firing them
			// right now
			if (rfocusMorph.test(type + jQuery.event.triggered)) {
				return;
			}

			if (type.indexOf(".") >= 0) {
				// Namespaced trigger; create a regexp to match event type in
				// handle()
				namespaces = type.split(".");
				type = namespaces.shift();
				namespaces.sort();
			}
			ontype = type.indexOf(":") < 0 && "on" + type;

			// Caller can pass in a jQuery.Event object, Object, or just an
			// event type string
			event = event[jQuery.expando] ? event : new jQuery.Event(type,
					typeof event === "object" && event);

			event.isTrigger = true;
			event.namespace = namespaces.join(".");
			event.namespace_re = event.namespace ? new RegExp("(^|\\.)"
					+ namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)") : null;

			// Clean up the event in case it is being reused
			event.result = undefined;
			if (!event.target) {
				event.target = elem;
			}

			// Clone any incoming data and prepend the event, creating the
			// handler arg list
			data = data == null ? [ event ] : jQuery.makeArray(data, [ event ]);

			// Allow special events to draw outside the lines
			special = jQuery.event.special[type] || {};
			if (!onlyHandlers && special.trigger
					&& special.trigger.apply(elem, data) === false) {
				return;
			}

			// Determine event propagation path in advance, per W3C events spec
			// (#9951)
			// Bubble up to document, then to window; watch for a global
			// ownerDocument var (#9724)
			if (!onlyHandlers && !special.noBubble && !jQuery.isWindow(elem)) {

				bubbleType = special.delegateType || type;
				if (!rfocusMorph.test(bubbleType + type)) {
					cur = cur.parentNode;
				}
				for (; cur; cur = cur.parentNode) {
					eventPath.push(cur);
					tmp = cur;
				}

				// Only add window if we got to document (e.g., not plain obj or
				// detached DOM)
				if (tmp === (elem.ownerDocument || document)) {
					eventPath.push(tmp.defaultView || tmp.parentWindow
							|| window);
				}
			}

			// Fire handlers on the event path
			i = 0;
			while ((cur = eventPath[i++]) && !event.isPropagationStopped()) {

				event.type = i > 1 ? bubbleType : special.bindType || type;

				// jQuery handler
				handle = (jQuery._data(cur, "events") || {})[event.type]
						&& jQuery._data(cur, "handle");
				if (handle) {
					handle.apply(cur, data);
				}

				// Native handler
				handle = ontype && cur[ontype];
				if (handle && jQuery.acceptData(cur) && handle.apply
						&& handle.apply(cur, data) === false) {
					event.preventDefault();
				}
			}
			event.type = type;

			// If nobody prevented the default action, do it now
			if (!onlyHandlers && !event.isDefaultPrevented()) {

				if ((!special._default || special._default.apply(
						elem.ownerDocument, data) === false)
						&& !(type === "click" && jQuery.nodeName(elem, "a"))
						&& jQuery.acceptData(elem)) {

					// Call a native DOM method on the target with the same name
					// name as the event.
					// Can't use an .isFunction() check here because IE6/7 fails
					// that test.
					// Don't do default actions on window, that's where global
					// variables be (#6170)
					if (ontype && elem[type] && !jQuery.isWindow(elem)) {

						// Don't re-trigger an onFOO event when we call its
						// FOO() method
						tmp = elem[ontype];

						if (tmp) {
							elem[ontype] = null;
						}

						// Prevent re-triggering of the same event, since we
						// already bubbled it above
						jQuery.event.triggered = type;
						try {
							elem[type]();
						} catch (e) {
							// IE<9 dies on focus/blur to hidden element
							// (#1486,#12518)
							// only reproducible on winXP IE8 native, not IE9 in
							// IE8 mode
						}
						jQuery.event.triggered = undefined;

						if (tmp) {
							elem[ontype] = tmp;
						}
					}
				}
			}

			return event.result;
		},

		dispatch : function(event) {

			// Make a writable jQuery.Event from the native event object
			event = jQuery.event.fix(event);

			var i, ret, handleObj, matched, j, handlerQueue = [], args = core_slice
					.call(arguments), handlers = (jQuery._data(this, "events") || {})[event.type]
					|| [], special = jQuery.event.special[event.type] || {};

			// Use the fix-ed jQuery.Event rather than the (read-only) native
			// event
			args[0] = event;
			event.delegateTarget = this;

			// Call the preDispatch hook for the mapped type, and let it bail if
			// desired
			if (special.preDispatch
					&& special.preDispatch.call(this, event) === false) {
				return;
			}

			// Determine handlers
			handlerQueue = jQuery.event.handlers.call(this, event, handlers);

			// Run delegates first; they may want to stop propagation beneath us
			i = 0;
			while ((matched = handlerQueue[i++])
					&& !event.isPropagationStopped()) {
				event.currentTarget = matched.elem;

				j = 0;
				while ((handleObj = matched.handlers[j++])
						&& !event.isImmediatePropagationStopped()) {

					// Triggered event must either 1) have no namespace, or
					// 2) have namespace(s) a subset or equal to those in the
					// bound event (both can have no namespace).
					if (!event.namespace_re
							|| event.namespace_re.test(handleObj.namespace)) {

						event.handleObj = handleObj;
						event.data = handleObj.data;

						ret = ((jQuery.event.special[handleObj.origType] || {}).handle || handleObj.handler)
								.apply(matched.elem, args);

						if (ret !== undefined) {
							if ((event.result = ret) === false) {
								event.preventDefault();
								event.stopPropagation();
							}
						}
					}
				}
			}

			// Call the postDispatch hook for the mapped type
			if (special.postDispatch) {
				special.postDispatch.call(this, event);
			}

			return event.result;
		},

		handlers : function(event, handlers) {
			var sel, handleObj, matches, i, handlerQueue = [], delegateCount = handlers.delegateCount, cur = event.target;

			// Find delegate handlers
			// Black-hole SVG <use> instance trees (#13180)
			// Avoid non-left-click bubbling in Firefox (#3861)
			if (delegateCount && cur.nodeType
					&& (!event.button || event.type !== "click")) {

				for (; cur != this; cur = cur.parentNode || this) {

					// Don't check non-elements (#13208)
					// Don't process clicks on disabled elements (#6911, #8165,
					// #11382, #11764)
					if (cur.nodeType === 1
							&& (cur.disabled !== true || event.type !== "click")) {
						matches = [];
						for (i = 0; i < delegateCount; i++) {
							handleObj = handlers[i];

							// Don't conflict with Object.prototype properties
							// (#13203)
							sel = handleObj.selector + " ";

							if (matches[sel] === undefined) {
								matches[sel] = handleObj.needsContext ? jQuery(
										sel, this).index(cur) >= 0 : jQuery
										.find(sel, this, null, [ cur ]).length;
							}
							if (matches[sel]) {
								matches.push(handleObj);
							}
						}
						if (matches.length) {
							handlerQueue.push({
								elem : cur,
								handlers : matches
							});
						}
					}
				}
			}

			// Add the remaining (directly-bound) handlers
			if (delegateCount < handlers.length) {
				handlerQueue.push({
					elem : this,
					handlers : handlers.slice(delegateCount)
				});
			}

			return handlerQueue;
		},

		fix : function(event) {
			if (event[jQuery.expando]) {
				return event;
			}

			// Create a writable copy of the event object and normalize some
			// properties
			var i, prop, copy, type = event.type, originalEvent = event, fixHook = this.fixHooks[type];

			if (!fixHook) {
				this.fixHooks[type] = fixHook = rmouseEvent.test(type) ? this.mouseHooks
						: rkeyEvent.test(type) ? this.keyHooks : {};
			}
			copy = fixHook.props ? this.props.concat(fixHook.props)
					: this.props;

			event = new jQuery.Event(originalEvent);

			i = copy.length;
			while (i--) {
				prop = copy[i];
				event[prop] = originalEvent[prop];
			}

			// Support: IE<9
			// Fix target property (#1925)
			if (!event.target) {
				event.target = originalEvent.srcElement || document;
			}

			// Support: Chrome 23+, Safari?
			// Target should not be a text node (#504, #13143)
			if (event.target.nodeType === 3) {
				event.target = event.target.parentNode;
			}

			// Support: IE<9
			// For mouse/key events, metaKey==false if it's undefined (#3368,
			// #11328)
			event.metaKey = !!event.metaKey;

			return fixHook.filter ? fixHook.filter(event, originalEvent)
					: event;
		},

		// Includes some event props shared by KeyEvent and MouseEvent
		props : "altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which"
				.split(" "),

		fixHooks : {},

		keyHooks : {
			props : "char charCode key keyCode".split(" "),
			filter : function(event, original) {

				// Add which for key events
				if (event.which == null) {
					event.which = original.charCode != null ? original.charCode
							: original.keyCode;
				}

				return event;
			}
		},

		mouseHooks : {
			props : "button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement"
					.split(" "),
			filter : function(event, original) {
				var body, eventDoc, doc, button = original.button, fromElement = original.fromElement;

				// Calculate pageX/Y if missing and clientX/Y available
				if (event.pageX == null && original.clientX != null) {
					eventDoc = event.target.ownerDocument || document;
					doc = eventDoc.documentElement;
					body = eventDoc.body;

					event.pageX = original.clientX
							+ (doc && doc.scrollLeft || body && body.scrollLeft || 0)
							- (doc && doc.clientLeft || body && body.clientLeft || 0);
					event.pageY = original.clientY
							+ (doc && doc.scrollTop || body && body.scrollTop || 0)
							- (doc && doc.clientTop || body && body.clientTop || 0);
				}

				// Add relatedTarget, if necessary
				if (!event.relatedTarget && fromElement) {
					event.relatedTarget = fromElement === event.target ? original.toElement
							: fromElement;
				}

				// Add which for click: 1 === left; 2 === middle; 3 === right
				// Note: button is not normalized, so don't use it
				if (!event.which && button !== undefined) {
					event.which = (button & 1 ? 1 : (button & 2 ? 3
							: (button & 4 ? 2 : 0)));
				}

				return event;
			}
		},

		special : {
			load : {
				// Prevent triggered image.load events from bubbling to
				// window.load
				noBubble : true
			},
			click : {
				// For checkbox, fire native event so checked state will be
				// right
				trigger : function() {
					if (jQuery.nodeName(this, "input")
							&& this.type === "checkbox" && this.click) {
						this.click();
						return false;
					}
				}
			},
			focus : {
				// Fire native event if possible so blur/focus sequence is
				// correct
				trigger : function() {
					if (this !== document.activeElement && this.focus) {
						try {
							this.focus();
							return false;
						} catch (e) {
							// Support: IE<9
							// If we error on focus to hidden element (#1486,
							// #12518),
							// let .trigger() run the handlers
						}
					}
				},
				delegateType : "focusin"
			},
			blur : {
				trigger : function() {
					if (this === document.activeElement && this.blur) {
						this.blur();
						return false;
					}
				},
				delegateType : "focusout"
			},

			beforeunload : {
				postDispatch : function(event) {

					// Even when returnValue equals to undefined Firefox will
					// still show alert
					if (event.result !== undefined) {
						event.originalEvent.returnValue = event.result;
					}
				}
			}
		},

		simulate : function(type, elem, event, bubble) {
			// Piggyback on a donor event to simulate a different one.
			// Fake originalEvent to avoid donor's stopPropagation, but if the
			// simulated event prevents default then we do the same on the
			// donor.
			var e = jQuery.extend(new jQuery.Event(), event, {
				type : type,
				isSimulated : true,
				originalEvent : {}
			});
			if (bubble) {
				jQuery.event.trigger(e, null, elem);
			} else {
				jQuery.event.dispatch.call(elem, e);
			}
			if (e.isDefaultPrevented()) {
				event.preventDefault();
			}
		}
	};

	jQuery.removeEvent = document.removeEventListener ? function(elem, type,
			handle) {
		if (elem.removeEventListener) {
			elem.removeEventListener(type, handle, false);
		}
	} : function(elem, type, handle) {
		var name = "on" + type;

		if (elem.detachEvent) {

			// #8545, #7054, preventing memory leaks for custom events in IE6-8
			// detachEvent needed property on element, by name of that event, to
			// properly expose it to GC
			if (typeof elem[name] === core_strundefined) {
				elem[name] = null;
			}

			elem.detachEvent(name, handle);
		}
	};

	jQuery.Event = function(src, props) {
		// Allow instantiation without the 'new' keyword
		if (!(this instanceof jQuery.Event)) {
			return new jQuery.Event(src, props);
		}

		// Event object
		if (src && src.type) {
			this.originalEvent = src;
			this.type = src.type;

			// Events bubbling up the document may have been marked as prevented
			// by a handler lower down the tree; reflect the correct value.
			this.isDefaultPrevented = (src.defaultPrevented
					|| src.returnValue === false || src.getPreventDefault
					&& src.getPreventDefault()) ? returnTrue : returnFalse;

			// Event type
		} else {
			this.type = src;
		}

		// Put explicitly provided properties onto the event object
		if (props) {
			jQuery.extend(this, props);
		}

		// Create a timestamp if incoming event doesn't have one
		this.timeStamp = src && src.timeStamp || jQuery.now();

		// Mark it as fixed
		this[jQuery.expando] = true;
	};

	// jQuery.Event is based on DOM3 Events as specified by the ECMAScript
	// Language Binding
	// http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html
	jQuery.Event.prototype = {
		isDefaultPrevented : returnFalse,
		isPropagationStopped : returnFalse,
		isImmediatePropagationStopped : returnFalse,

		preventDefault : function() {
			var e = this.originalEvent;

			this.isDefaultPrevented = returnTrue;
			if (!e) {
				return;
			}

			// If preventDefault exists, run it on the original event
			if (e.preventDefault) {
				e.preventDefault();

				// Support: IE
				// Otherwise set the returnValue property of the original event
				// to false
			} else {
				e.returnValue = false;
			}
		},
		stopPropagation : function() {
			var e = this.originalEvent;

			this.isPropagationStopped = returnTrue;
			if (!e) {
				return;
			}
			// If stopPropagation exists, run it on the original event
			if (e.stopPropagation) {
				e.stopPropagation();
			}

			// Support: IE
			// Set the cancelBubble property of the original event to true
			e.cancelBubble = true;
		},
		stopImmediatePropagation : function() {
			this.isImmediatePropagationStopped = returnTrue;
			this.stopPropagation();
		}
	};

	// Create mouseenter/leave events using mouseover/out and event-time checks
	jQuery
			.each(
					{
						mouseenter : "mouseover",
						mouseleave : "mouseout"
					},
					function(orig, fix) {
						jQuery.event.special[orig] = {
							delegateType : fix,
							bindType : fix,

							handle : function(event) {
								var ret, target = this, related = event.relatedTarget, handleObj = event.handleObj;

								// For mousenter/leave call the handler if
								// related is outside the target.
								// NB: No relatedTarget if the mouse
								// left/entered the browser window
								if (!related
										|| (related !== target && !jQuery
												.contains(target, related))) {
									event.type = handleObj.origType;
									ret = handleObj.handler.apply(this,
											arguments);
									event.type = fix;
								}
								return ret;
							}
						};
					});

	// IE submit delegation
	if (!jQuery.support.submitBubbles) {

		jQuery.event.special.submit = {
			setup : function() {
				// Only need this for delegated form submit events
				if (jQuery.nodeName(this, "form")) {
					return false;
				}

				// Lazy-add a submit handler when a descendant form may
				// potentially be submitted
				jQuery.event
						.add(
								this,
								"click._submit keypress._submit",
								function(e) {
									// Node name check avoids a VML-related
									// crash in IE (#9807)
									var elem = e.target, form = jQuery
											.nodeName(elem, "input")
											|| jQuery.nodeName(elem, "button") ? elem.form
											: undefined;
									if (form
											&& !jQuery._data(form,
													"submitBubbles")) {
										jQuery.event
												.add(
														form,
														"submit._submit",
														function(event) {
															event._submit_bubble = true;
														});
										jQuery._data(form, "submitBubbles",
												true);
									}
								});
				// return undefined since we don't need an event listener
			},

			postDispatch : function(event) {
				// If form was submitted by the user, bubble the event up the
				// tree
				if (event._submit_bubble) {
					delete event._submit_bubble;
					if (this.parentNode && !event.isTrigger) {
						jQuery.event.simulate("submit", this.parentNode, event,
								true);
					}
				}
			},

			teardown : function() {
				// Only need this for delegated form submit events
				if (jQuery.nodeName(this, "form")) {
					return false;
				}

				// Remove delegated handlers; cleanData eventually reaps submit
				// handlers attached above
				jQuery.event.remove(this, "._submit");
			}
		};
	}

	// IE change delegation and checkbox/radio fix
	if (!jQuery.support.changeBubbles) {

		jQuery.event.special.change = {

			setup : function() {

				if (rformElems.test(this.nodeName)) {
					// IE doesn't fire change on a check/radio until blur;
					// trigger it on click
					// after a propertychange. Eat the blur-change in
					// special.change.handle.
					// This still fires onchange a second time for check/radio
					// after blur.
					if (this.type === "checkbox" || this.type === "radio") {
						jQuery.event
								.add(
										this,
										"propertychange._change",
										function(event) {
											if (event.originalEvent.propertyName === "checked") {
												this._just_changed = true;
											}
										});
						jQuery.event
								.add(this, "click._change",
										function(event) {
											if (this._just_changed
													&& !event.isTrigger) {
												this._just_changed = false;
											}
											// Allow triggered, simulated change
											// events (#11500)
											jQuery.event.simulate("change",
													this, event, true);
										});
					}
					return false;
				}
				// Delegated event; lazy-add a change handler on descendant
				// inputs
				jQuery.event.add(this, "beforeactivate._change", function(e) {
					var elem = e.target;

					if (rformElems.test(elem.nodeName)
							&& !jQuery._data(elem, "changeBubbles")) {
						jQuery.event.add(elem, "change._change",
								function(event) {
									if (this.parentNode && !event.isSimulated
											&& !event.isTrigger) {
										jQuery.event.simulate("change",
												this.parentNode, event, true);
									}
								});
						jQuery._data(elem, "changeBubbles", true);
					}
				});
			},

			handle : function(event) {
				var elem = event.target;

				// Swallow native change events from checkbox/radio, we already
				// triggered them above
				if (this !== elem || event.isSimulated || event.isTrigger
						|| (elem.type !== "radio" && elem.type !== "checkbox")) {
					return event.handleObj.handler.apply(this, arguments);
				}
			},

			teardown : function() {
				jQuery.event.remove(this, "._change");

				return !rformElems.test(this.nodeName);
			}
		};
	}

	// Create "bubbling" focus and blur events
	if (!jQuery.support.focusinBubbles) {
		jQuery.each({
			focus : "focusin",
			blur : "focusout"
		}, function(orig, fix) {

			// Attach a single capturing handler while someone wants
			// focusin/focusout
			var attaches = 0, handler = function(event) {
				jQuery.event.simulate(fix, event.target, jQuery.event
						.fix(event), true);
			};

			jQuery.event.special[fix] = {
				setup : function() {
					if (attaches++ === 0) {
						document.addEventListener(orig, handler, true);
					}
				},
				teardown : function() {
					if (--attaches === 0) {
						document.removeEventListener(orig, handler, true);
					}
				}
			};
		});
	}

	jQuery.fn.extend({

		on : function(types, selector, data, fn, /* INTERNAL */one) {
			var type, origFn;

			// Types can be a map of types/handlers
			if (typeof types === "object") {
				// ( types-Object, selector, data )
				if (typeof selector !== "string") {
					// ( types-Object, data )
					data = data || selector;
					selector = undefined;
				}
				for (type in types) {
					this.on(type, selector, data, types[type], one);
				}
				return this;
			}

			if (data == null && fn == null) {
				// ( types, fn )
				fn = selector;
				data = selector = undefined;
			} else if (fn == null) {
				if (typeof selector === "string") {
					// ( types, selector, fn )
					fn = data;
					data = undefined;
				} else {
					// ( types, data, fn )
					fn = data;
					data = selector;
					selector = undefined;
				}
			}
			if (fn === false) {
				fn = returnFalse;
			} else if (!fn) {
				return this;
			}

			if (one === 1) {
				origFn = fn;
				fn = function(event) {
					// Can use an empty set, since event contains the info
					jQuery().off(event);
					return origFn.apply(this, arguments);
				};
				// Use same guid so caller can remove using origFn
				fn.guid = origFn.guid || (origFn.guid = jQuery.guid++);
			}
			return this.each(function() {
				jQuery.event.add(this, types, fn, data, selector);
			});
		},
		one : function(types, selector, data, fn) {
			return this.on(types, selector, data, fn, 1);
		},
		off : function(types, selector, fn) {
			var handleObj, type;
			if (types && types.preventDefault && types.handleObj) {
				// ( event ) dispatched jQuery.Event
				handleObj = types.handleObj;
				jQuery(types.delegateTarget).off(
						handleObj.namespace ? handleObj.origType + "."
								+ handleObj.namespace : handleObj.origType,
						handleObj.selector, handleObj.handler);
				return this;
			}
			if (typeof types === "object") {
				// ( types-object [, selector] )
				for (type in types) {
					this.off(type, selector, types[type]);
				}
				return this;
			}
			if (selector === false || typeof selector === "function") {
				// ( types [, fn] )
				fn = selector;
				selector = undefined;
			}
			if (fn === false) {
				fn = returnFalse;
			}
			return this.each(function() {
				jQuery.event.remove(this, types, fn, selector);
			});
		},

		bind : function(types, data, fn) {
			return this.on(types, null, data, fn);
		},
		unbind : function(types, fn) {
			return this.off(types, null, fn);
		},

		delegate : function(selector, types, data, fn) {
			return this.on(types, selector, data, fn);
		},
		undelegate : function(selector, types, fn) {
			// ( namespace ) or ( selector, types [, fn] )
			return arguments.length === 1 ? this.off(selector, "**") : this
					.off(types, selector || "**", fn);
		},

		trigger : function(type, data) {
			return this.each(function() {
				jQuery.event.trigger(type, data, this);
			});
		},
		triggerHandler : function(type, data) {
			var elem = this[0];
			if (elem) {
				return jQuery.event.trigger(type, data, elem, true);
			}
		}
	});
	/*
	 * ! Sizzle CSS Selector Engine Copyright 2012 jQuery Foundation and other
	 * contributors Released under the MIT license http://sizzlejs.com/
	 */
	(function(window, undefined) {

		var i, cachedruns, Expr, getText, isXML, compile, hasDuplicate, outermostContext,

		// Local document vars
		setDocument, document, docElem, documentIsXML, rbuggyQSA, rbuggyMatches, matches, contains, sortOrder,

		// Instance-specific data
		expando = "sizzle" + -(new Date()), preferredDoc = window.document, support = {}, dirruns = 0, done = 0, classCache = createCache(), tokenCache = createCache(), compilerCache = createCache(),

		// General-purpose constants
		strundefined = typeof undefined, MAX_NEGATIVE = 1 << 31,

		// Array methods
		arr = [], pop = arr.pop, push = arr.push, slice = arr.slice,
		// Use a stripped-down indexOf if we can't use a native one
		indexOf = arr.indexOf || function(elem) {
			var i = 0, len = this.length;
			for (; i < len; i++) {
				if (this[i] === elem) {
					return i;
				}
			}
			return -1;
		},

		// Regular expressions

		// Whitespace characters http://www.w3.org/TR/css3-selectors/#whitespace
		whitespace = "[\\x20\\t\\r\\n\\f]",
		// http://www.w3.org/TR/css3-syntax/#characters
		characterEncoding = "(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",

		// Loosely modeled on CSS identifier characters
		// An unquoted value should be a CSS identifier
		// http://www.w3.org/TR/css3-selectors/#attribute-selectors
		// Proper syntax:
		// http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier
		identifier = characterEncoding.replace("w", "w#"),

		// Acceptable operators
		// http://www.w3.org/TR/selectors/#attribute-selectors
		operators = "([*^$|!~]?=)", attributes = "\\[" + whitespace + "*("
				+ characterEncoding + ")" + whitespace + "*(?:" + operators
				+ whitespace + "*(?:(['\"])((?:\\\\.|[^\\\\])*?)\\3|("
				+ identifier + ")|)|)" + whitespace + "*\\]",

		// Prefer arguments quoted,
		// then not containing pseudos/brackets,
		// then attribute selectors/non-parenthetical expressions,
		// then anything else
		// These preferences are here to reduce the number of selectors
		// needing tokenize in the PSEUDO preFilter
		pseudos = ":("
				+ characterEncoding
				+ ")(?:\\(((['\"])((?:\\\\.|[^\\\\])*?)\\3|((?:\\\\.|[^\\\\()[\\]]|"
				+ attributes.replace(3, 8) + ")*)|.*)\\)|)",

		// Leading and non-escaped trailing whitespace, capturing some
		// non-whitespace characters preceding the latter
		rtrim = new RegExp("^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)"
				+ whitespace + "+$", "g"),

		rcomma = new RegExp("^" + whitespace + "*," + whitespace + "*"), rcombinators = new RegExp(
				"^" + whitespace + "*([\\x20\\t\\r\\n\\f>+~])" + whitespace
						+ "*"), rpseudo = new RegExp(pseudos), ridentifier = new RegExp(
				"^" + identifier + "$"),

		matchExpr = {
			"ID" : new RegExp("^#(" + characterEncoding + ")"),
			"CLASS" : new RegExp("^\\.(" + characterEncoding + ")"),
			"NAME" : new RegExp("^\\[name=['\"]?(" + characterEncoding
					+ ")['\"]?\\]"),
			"TAG" : new RegExp("^(" + characterEncoding.replace("w", "w*")
					+ ")"),
			"ATTR" : new RegExp("^" + attributes),
			"PSEUDO" : new RegExp("^" + pseudos),
			"CHILD" : new RegExp(
					"^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("
							+ whitespace + "*(even|odd|(([+-]|)(\\d*)n|)"
							+ whitespace + "*(?:([+-]|)" + whitespace
							+ "*(\\d+)|))" + whitespace + "*\\)|)", "i"),
			// For use in libraries implementing .is()
			// We use this for POS matching in `select`
			"needsContext" : new RegExp("^" + whitespace
					+ "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("
					+ whitespace + "*((?:-\\d)?\\d*)" + whitespace
					+ "*\\)|)(?=[^-]|$)", "i")
		},

		rsibling = /[\x20\t\r\n\f]*[+~]/,

		rnative = /^[^{]+\{\s*\[native code/,

		// Easily-parseable/retrievable ID or TAG or CLASS selectors
		rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,

		rinputs = /^(?:input|select|textarea|button)$/i, rheader = /^h\d$/i,

		rescape = /'|\\/g, rattributeQuotes = /\=[\x20\t\r\n\f]*([^'"\]]*)[\x20\t\r\n\f]*\]/g,

		// CSS escapes
		// http://www.w3.org/TR/CSS21/syndata.html#escaped-characters
		runescape = /\\([\da-fA-F]{1,6}[\x20\t\r\n\f]?|.)/g, funescape = function(
				_, escaped) {
			var high = "0x" + escaped - 0x10000;
			// NaN means non-codepoint
			return high !== high ? escaped :
			// BMP codepoint
			high < 0 ? String.fromCharCode(high + 0x10000) :
			// Supplemental Plane codepoint (surrogate pair)
			String.fromCharCode(high >> 10 | 0xD800, high & 0x3FF | 0xDC00);
		};

		// Use a stripped-down slice if we can't use a native one
		try {
			slice.call(preferredDoc.documentElement.childNodes, 0)[0].nodeType;
		} catch (e) {
			slice = function(i) {
				var elem, results = [];
				while ((elem = this[i++])) {
					results.push(elem);
				}
				return results;
			};
		}

		/**
		 * For feature detection
		 * 
		 * @param {Function}
		 *            fn The function to test for native support
		 */
		function isNative(fn) {
			return rnative.test(fn + "");
		}

		/**
		 * Create key-value caches of limited size
		 * 
		 * @returns {Function(string, Object)} Returns the Object data after
		 *          storing it on itself with property name the (space-suffixed)
		 *          string and (if the cache is larger than Expr.cacheLength)
		 *          deleting the oldest entry
		 */
		function createCache() {
			var cache, keys = [];

			return (cache = function(key, value) {
				// Use (key + " ") to avoid collision with native prototype
				// properties (see Issue #157)
				if (keys.push(key += " ") > Expr.cacheLength) {
					// Only keep the most recent entries
					delete cache[keys.shift()];
				}
				return (cache[key] = value);
			});
		}

		/**
		 * Mark a function for special use by Sizzle
		 * 
		 * @param {Function}
		 *            fn The function to mark
		 */
		function markFunction(fn) {
			fn[expando] = true;
			return fn;
		}

		/**
		 * Support testing using an element
		 * 
		 * @param {Function}
		 *            fn Passed the created div and expects a boolean result
		 */
		function assert(fn) {
			var div = document.createElement("div");

			try {
				return fn(div);
			} catch (e) {
				return false;
			} finally {
				// release memory in IE
				div = null;
			}
		}

		function Sizzle(selector, context, results, seed) {
			var match, elem, m, nodeType,
			// QSA vars
			i, groups, old, nid, newContext, newSelector;

			if ((context ? context.ownerDocument || context : preferredDoc) !== document) {
				setDocument(context);
			}

			context = context || document;
			results = results || [];

			if (!selector || typeof selector !== "string") {
				return results;
			}

			if ((nodeType = context.nodeType) !== 1 && nodeType !== 9) {
				return [];
			}

			if (!documentIsXML && !seed) {

				// Shortcuts
				if ((match = rquickExpr.exec(selector))) {
					// Speed-up: Sizzle("#ID")
					if ((m = match[1])) {
						if (nodeType === 9) {
							elem = context.getElementById(m);
							// Check parentNode to catch when Blackberry 4.6
							// returns
							// nodes that are no longer in the document #6963
							if (elem && elem.parentNode) {
								// Handle the case where IE, Opera, and Webkit
								// return items
								// by name instead of ID
								if (elem.id === m) {
									results.push(elem);
									return results;
								}
							} else {
								return results;
							}
						} else {
							// Context is not a document
							if (context.ownerDocument
									&& (elem = context.ownerDocument
											.getElementById(m))
									&& contains(context, elem) && elem.id === m) {
								results.push(elem);
								return results;
							}
						}

						// Speed-up: Sizzle("TAG")
					} else if (match[2]) {
						push.apply(results, slice.call(context
								.getElementsByTagName(selector), 0));
						return results;

						// Speed-up: Sizzle(".CLASS")
					} else if ((m = match[3]) && support.getByClassName
							&& context.getElementsByClassName) {
						push.apply(results, slice.call(context
								.getElementsByClassName(m), 0));
						return results;
					}
				}

				// QSA path
				if (support.qsa && !rbuggyQSA.test(selector)) {
					old = true;
					nid = expando;
					newContext = context;
					newSelector = nodeType === 9 && selector;

					// qSA works strangely on Element-rooted queries
					// We can work around this by specifying an extra ID on the
					// root
					// and working up from there (Thanks to Andrew Dupont for
					// the technique)
					// IE 8 doesn't work on object elements
					if (nodeType === 1
							&& context.nodeName.toLowerCase() !== "object") {
						groups = tokenize(selector);

						if ((old = context.getAttribute("id"))) {
							nid = old.replace(rescape, "\\$&");
						} else {
							context.setAttribute("id", nid);
						}
						nid = "[id='" + nid + "'] ";

						i = groups.length;
						while (i--) {
							groups[i] = nid + toSelector(groups[i]);
						}
						newContext = rsibling.test(selector)
								&& context.parentNode || context;
						newSelector = groups.join(",");
					}

					if (newSelector) {
						try {
							push.apply(results, slice.call(newContext
									.querySelectorAll(newSelector), 0));
							return results;
						} catch (qsaError) {
						} finally {
							if (!old) {
								context.removeAttribute("id");
							}
						}
					}
				}
			}

			// All others
			return select(selector.replace(rtrim, "$1"), context, results, seed);
		}

		/**
		 * Detect xml
		 * 
		 * @param {Element|Object}
		 *            elem An element or a document
		 */
		isXML = Sizzle.isXML = function(elem) {
			// documentElement is verified for cases where it doesn't yet exist
			// (such as loading iframes in IE - #4833)
			var documentElement = elem
					&& (elem.ownerDocument || elem).documentElement;
			return documentElement ? documentElement.nodeName !== "HTML"
					: false;
		};

		/**
		 * Sets document-related variables once based on the current document
		 * 
		 * @param {Element|Object}
		 *            [doc] An element or document object to use to set the
		 *            document
		 * @returns {Object} Returns the current document
		 */
		setDocument = Sizzle.setDocument = function(node) {
			var doc = node ? node.ownerDocument || node : preferredDoc;

			// If no document and documentElement is available, return
			if (doc === document || doc.nodeType !== 9 || !doc.documentElement) {
				return document;
			}

			// Set our document
			document = doc;
			docElem = doc.documentElement;

			// Support tests
			documentIsXML = isXML(doc);

			// Check if getElementsByTagName("*") returns only elements
			support.tagNameNoComments = assert(function(div) {
				div.appendChild(doc.createComment(""));
				return !div.getElementsByTagName("*").length;
			});

			// Check if attributes should be retrieved by attribute nodes
			support.attributes = assert(function(div) {
				div.innerHTML = "<select></select>";
				var type = typeof div.lastChild.getAttribute("multiple");
				// IE8 returns a string for some attributes even when not
				// present
				return type !== "boolean" && type !== "string";
			});

			// Check if getElementsByClassName can be trusted
			support.getByClassName = assert(function(div) {
				// Opera can't find a second classname (in 9.6)
				div.innerHTML = "<div class='hidden e'></div><div class='hidden'></div>";
				if (!div.getElementsByClassName
						|| !div.getElementsByClassName("e").length) {
					return false;
				}

				// Safari 3.2 caches class attributes and doesn't catch changes
				div.lastChild.className = "e";
				return div.getElementsByClassName("e").length === 2;
			});

			// Check if getElementById returns elements by name
			// Check if getElementsByName privileges form controls or returns
			// elements by ID
			support.getByName = assert(function(div) {
				// Inject content
				div.id = expando + 0;
				div.innerHTML = "<a name='" + expando + "'></a><div name='"
						+ expando + "'></div>";
				docElem.insertBefore(div, docElem.firstChild);

				// Test
				var pass = doc.getElementsByName &&
				// buggy browsers will return fewer than the correct 2
				doc.getElementsByName(expando).length === 2 +
				// buggy browsers will return more than the correct 0
				doc.getElementsByName(expando + 0).length;
				support.getIdNotName = !doc.getElementById(expando);

				// Cleanup
				docElem.removeChild(div);

				return pass;
			});

			// IE6/7 return modified attributes
			Expr.attrHandle = assert(function(div) {
				div.innerHTML = "<a href='#'></a>";
				return div.firstChild
						&& typeof div.firstChild.getAttribute !== strundefined
						&& div.firstChild.getAttribute("href") === "#";
			}) ? {} : {
				"href" : function(elem) {
					return elem.getAttribute("href", 2);
				},
				"type" : function(elem) {
					return elem.getAttribute("type");
				}
			};

			// ID find and filter
			if (support.getIdNotName) {
				Expr.find["ID"] = function(id, context) {
					if (typeof context.getElementById !== strundefined
							&& !documentIsXML) {
						var m = context.getElementById(id);
						// Check parentNode to catch when Blackberry 4.6 returns
						// nodes that are no longer in the document #6963
						return m && m.parentNode ? [ m ] : [];
					}
				};
				Expr.filter["ID"] = function(id) {
					var attrId = id.replace(runescape, funescape);
					return function(elem) {
						return elem.getAttribute("id") === attrId;
					};
				};
			} else {
				Expr.find["ID"] = function(id, context) {
					if (typeof context.getElementById !== strundefined
							&& !documentIsXML) {
						var m = context.getElementById(id);

						return m ? m.id === id
								|| typeof m.getAttributeNode !== strundefined
								&& m.getAttributeNode("id").value === id ? [ m ]
								: undefined
								: [];
					}
				};
				Expr.filter["ID"] = function(id) {
					var attrId = id.replace(runescape, funescape);
					return function(elem) {
						var node = typeof elem.getAttributeNode !== strundefined
								&& elem.getAttributeNode("id");
						return node && node.value === attrId;
					};
				};
			}

			// Tag
			Expr.find["TAG"] = support.tagNameNoComments ? function(tag,
					context) {
				if (typeof context.getElementsByTagName !== strundefined) {
					return context.getElementsByTagName(tag);
				}
			} : function(tag, context) {
				var elem, tmp = [], i = 0, results = context
						.getElementsByTagName(tag);

				// Filter out possible comments
				if (tag === "*") {
					while ((elem = results[i++])) {
						if (elem.nodeType === 1) {
							tmp.push(elem);
						}
					}

					return tmp;
				}
				return results;
			};

			// Name
			Expr.find["NAME"] = support.getByName && function(tag, context) {
				if (typeof context.getElementsByName !== strundefined) {
					return context.getElementsByName(name);
				}
			};

			// Class
			Expr.find["CLASS"] = support.getByClassName
					&& function(className, context) {
						if (typeof context.getElementsByClassName !== strundefined
								&& !documentIsXML) {
							return context.getElementsByClassName(className);
						}
					};

			// QSA and matchesSelector support

			// matchesSelector(:active) reports false when true (IE9/Opera 11.5)
			rbuggyMatches = [];

			// qSa(:focus) reports false when true (Chrome 21),
			// no need to also add to buggyMatches since matches checks buggyQSA
			// A support test would require too much code (would include
			// document ready)
			rbuggyQSA = [ ":focus" ];

			if ((support.qsa = isNative(doc.querySelectorAll))) {
				// Build QSA regex
				// Regex strategy adopted from Diego Perini
				assert(function(div) {
					// Select is set to empty string on purpose
					// This is to test IE's treatment of not explictly
					// setting a boolean content attribute,
					// since its presence should be enough
					// http://bugs.jquery.com/ticket/12359
					div.innerHTML = "<select><option selected=''></option></select>";

					// IE8 - Some boolean attributes are not treated correctly
					if (!div.querySelectorAll("[selected]").length) {
						rbuggyQSA
								.push("\\["
										+ whitespace
										+ "*(?:checked|disabled|ismap|multiple|readonly|selected|value)");
					}

					// Webkit/Opera - :checked should return selected option
					// elements
					// http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
					// IE8 throws error here and will not see later tests
					if (!div.querySelectorAll(":checked").length) {
						rbuggyQSA.push(":checked");
					}
				});

				assert(function(div) {

					// Opera 10-12/IE8 - ^= $= *= and empty values
					// Should not select anything
					div.innerHTML = "<input type='hidden' i=''/>";
					if (div.querySelectorAll("[i^='']").length) {
						rbuggyQSA.push("[*^$]=" + whitespace + "*(?:\"\"|'')");
					}

					// FF 3.5 - :enabled/:disabled and hidden elements (hidden
					// elements are still enabled)
					// IE8 throws error here and will not see later tests
					if (!div.querySelectorAll(":enabled").length) {
						rbuggyQSA.push(":enabled", ":disabled");
					}

					// Opera 10-11 does not throw on post-comma invalid pseudos
					div.querySelectorAll("*,:x");
					rbuggyQSA.push(",.*:");
				});
			}

			if ((support.matchesSelector = isNative((matches = docElem.matchesSelector
					|| docElem.mozMatchesSelector
					|| docElem.webkitMatchesSelector
					|| docElem.oMatchesSelector || docElem.msMatchesSelector)))) {

				assert(function(div) {
					// Check to see if it's possible to do matchesSelector
					// on a disconnected node (IE 9)
					support.disconnectedMatch = matches.call(div, "div");

					// This should fail with an exception
					// Gecko does not error, returns false instead
					matches.call(div, "[s!='']:x");
					rbuggyMatches.push("!=", pseudos);
				});
			}

			rbuggyQSA = new RegExp(rbuggyQSA.join("|"));
			rbuggyMatches = new RegExp(rbuggyMatches.join("|"));

			// Element contains another
			// Purposefully does not implement inclusive descendent
			// As in, an element does not contain itself
			contains = isNative(docElem.contains)
					|| docElem.compareDocumentPosition ? function(a, b) {
				var adown = a.nodeType === 9 ? a.documentElement : a, bup = b
						&& b.parentNode;
				return a === bup
						|| !!(bup && bup.nodeType === 1 && (adown.contains ? adown
								.contains(bup)
								: a.compareDocumentPosition
										&& a.compareDocumentPosition(bup) & 16));
			}
					: function(a, b) {
						if (b) {
							while ((b = b.parentNode)) {
								if (b === a) {
									return true;
								}
							}
						}
						return false;
					};

			// Document order sorting
			sortOrder = docElem.compareDocumentPosition ? function(a, b) {
				var compare;

				if (a === b) {
					hasDuplicate = true;
					return 0;
				}

				if ((compare = b.compareDocumentPosition
						&& a.compareDocumentPosition
						&& a.compareDocumentPosition(b))) {
					if (compare & 1 || a.parentNode
							&& a.parentNode.nodeType === 11) {
						if (a === doc || contains(preferredDoc, a)) {
							return -1;
						}
						if (b === doc || contains(preferredDoc, b)) {
							return 1;
						}
						return 0;
					}
					return compare & 4 ? -1 : 1;
				}

				return a.compareDocumentPosition ? -1 : 1;
			}
					: function(a, b) {
						var cur, i = 0, aup = a.parentNode, bup = b.parentNode, ap = [ a ], bp = [ b ];

						// Exit early if the nodes are identical
						if (a === b) {
							hasDuplicate = true;
							return 0;

							// Parentless nodes are either documents or
							// disconnected
						} else if (!aup || !bup) {
							return a === doc ? -1 : b === doc ? 1 : aup ? -1
									: bup ? 1 : 0;

							// If the nodes are siblings, we can do a quick
							// check
						} else if (aup === bup) {
							return siblingCheck(a, b);
						}

						// Otherwise we need full lists of their ancestors for
						// comparison
						cur = a;
						while ((cur = cur.parentNode)) {
							ap.unshift(cur);
						}
						cur = b;
						while ((cur = cur.parentNode)) {
							bp.unshift(cur);
						}

						// Walk down the tree looking for a discrepancy
						while (ap[i] === bp[i]) {
							i++;
						}

						return i ?
						// Do a sibling check if the nodes have a common
						// ancestor
						siblingCheck(ap[i], bp[i]) :

						// Otherwise nodes in our document sort first
						ap[i] === preferredDoc ? -1
								: bp[i] === preferredDoc ? 1 : 0;
					};

			// Always assume the presence of duplicates if sort doesn't
			// pass them to our comparison function (as in Google Chrome).
			hasDuplicate = false;
			[ 0, 0 ].sort(sortOrder);
			support.detectDuplicates = hasDuplicate;

			return document;
		};

		Sizzle.matches = function(expr, elements) {
			return Sizzle(expr, null, null, elements);
		};

		Sizzle.matchesSelector = function(elem, expr) {
			// Set document vars if needed
			if ((elem.ownerDocument || elem) !== document) {
				setDocument(elem);
			}

			// Make sure that attribute selectors are quoted
			expr = expr.replace(rattributeQuotes, "='$1']");

			// rbuggyQSA always contains :focus, so no need for an existence
			// check
			if (support.matchesSelector && !documentIsXML
					&& (!rbuggyMatches || !rbuggyMatches.test(expr))
					&& !rbuggyQSA.test(expr)) {
				try {
					var ret = matches.call(elem, expr);

					// IE 9's matchesSelector returns false on disconnected
					// nodes
					if (ret || support.disconnectedMatch ||
					// As well, disconnected nodes are said to be in a document
					// fragment in IE 9
					elem.document && elem.document.nodeType !== 11) {
						return ret;
					}
				} catch (e) {
				}
			}

			return Sizzle(expr, document, null, [ elem ]).length > 0;
		};

		Sizzle.contains = function(context, elem) {
			// Set document vars if needed
			if ((context.ownerDocument || context) !== document) {
				setDocument(context);
			}
			return contains(context, elem);
		};

		Sizzle.attr = function(elem, name) {
			var val;

			// Set document vars if needed
			if ((elem.ownerDocument || elem) !== document) {
				setDocument(elem);
			}

			if (!documentIsXML) {
				name = name.toLowerCase();
			}
			if ((val = Expr.attrHandle[name])) {
				return val(elem);
			}
			if (documentIsXML || support.attributes) {
				return elem.getAttribute(name);
			}
			return ((val = elem.getAttributeNode(name)) || elem
					.getAttribute(name))
					&& elem[name] === true ? name
					: val && val.specified ? val.value : null;
		};

		Sizzle.error = function(msg) {
			throw new Error("Syntax error, unrecognized expression: " + msg);
		};

		// Document sorting and removing duplicates
		Sizzle.uniqueSort = function(results) {
			var elem, duplicates = [], i = 1, j = 0;

			// Unless we *know* we can detect duplicates, assume their presence
			hasDuplicate = !support.detectDuplicates;
			results.sort(sortOrder);

			if (hasDuplicate) {
				for (; (elem = results[i]); i++) {
					if (elem === results[i - 1]) {
						j = duplicates.push(i);
					}
				}
				while (j--) {
					results.splice(duplicates[j], 1);
				}
			}

			return results;
		};

		function siblingCheck(a, b) {
			var cur = b && a, diff = cur && (~b.sourceIndex || MAX_NEGATIVE)
					- (~a.sourceIndex || MAX_NEGATIVE);

			// Use IE sourceIndex if available on both nodes
			if (diff) {
				return diff;
			}

			// Check if b follows a
			if (cur) {
				while ((cur = cur.nextSibling)) {
					if (cur === b) {
						return -1;
					}
				}
			}

			return a ? 1 : -1;
		}

		// Returns a function to use in pseudos for input types
		function createInputPseudo(type) {
			return function(elem) {
				var name = elem.nodeName.toLowerCase();
				return name === "input" && elem.type === type;
			};
		}

		// Returns a function to use in pseudos for buttons
		function createButtonPseudo(type) {
			return function(elem) {
				var name = elem.nodeName.toLowerCase();
				return (name === "input" || name === "button")
						&& elem.type === type;
			};
		}

		// Returns a function to use in pseudos for positionals
		function createPositionalPseudo(fn) {
			return markFunction(function(argument) {
				argument = +argument;
				return markFunction(function(seed, matches) {
					var j, matchIndexes = fn([], seed.length, argument), i = matchIndexes.length;

					// Match elements found at the specified indexes
					while (i--) {
						if (seed[(j = matchIndexes[i])]) {
							seed[j] = !(matches[j] = seed[j]);
						}
					}
				});
			});
		}

		/**
		 * Utility function for retrieving the text value of an array of DOM
		 * nodes
		 * 
		 * @param {Array|Element}
		 *            elem
		 */
		getText = Sizzle.getText = function(elem) {
			var node, ret = "", i = 0, nodeType = elem.nodeType;

			if (!nodeType) {
				// If no nodeType, this is expected to be an array
				for (; (node = elem[i]); i++) {
					// Do not traverse comment nodes
					ret += getText(node);
				}
			} else if (nodeType === 1 || nodeType === 9 || nodeType === 11) {
				// Use textContent for elements
				// innerText usage removed for consistency of new lines (see
				// #11153)
				if (typeof elem.textContent === "string") {
					return elem.textContent;
				} else {
					// Traverse its children
					for (elem = elem.firstChild; elem; elem = elem.nextSibling) {
						ret += getText(elem);
					}
				}
			} else if (nodeType === 3 || nodeType === 4) {
				return elem.nodeValue;
			}
			// Do not include comment or processing instruction nodes

			return ret;
		};

		Expr = Sizzle.selectors = {

			// Can be adjusted by the user
			cacheLength : 50,

			createPseudo : markFunction,

			match : matchExpr,

			find : {},

			relative : {
				">" : {
					dir : "parentNode",
					first : true
				},
				" " : {
					dir : "parentNode"
				},
				"+" : {
					dir : "previousSibling",
					first : true
				},
				"~" : {
					dir : "previousSibling"
				}
			},

			preFilter : {
				"ATTR" : function(match) {
					match[1] = match[1].replace(runescape, funescape);

					// Move the given value to match[3] whether quoted or
					// unquoted
					match[3] = (match[4] || match[5] || "").replace(runescape,
							funescape);

					if (match[2] === "~=") {
						match[3] = " " + match[3] + " ";
					}

					return match.slice(0, 4);
				},

				"CHILD" : function(match) {
					/*
					 * matches from matchExpr["CHILD"] 1 type (only|nth|...) 2
					 * what (child|of-type) 3 argument
					 * (even|odd|\d*|\d*n([+-]\d+)?|...) 4 xn-component of xn+y
					 * argument ([+-]?\d*n|) 5 sign of xn-component 6 x of
					 * xn-component 7 sign of y-component 8 y of y-component
					 */
					match[1] = match[1].toLowerCase();

					if (match[1].slice(0, 3) === "nth") {
						// nth-* requires argument
						if (!match[3]) {
							Sizzle.error(match[0]);
						}

						// numeric x and y parameters for Expr.filter.CHILD
						// remember that false/true cast respectively to 0/1
						match[4] = +(match[4] ? match[5] + (match[6] || 1)
								: 2 * (match[3] === "even" || match[3] === "odd"));
						match[5] = +((match[7] + match[8]) || match[3] === "odd");

						// other types prohibit arguments
					} else if (match[3]) {
						Sizzle.error(match[0]);
					}

					return match;
				},

				"PSEUDO" : function(match) {
					var excess, unquoted = !match[5] && match[2];

					if (matchExpr["CHILD"].test(match[0])) {
						return null;
					}

					// Accept quoted arguments as-is
					if (match[4]) {
						match[2] = match[4];

						// Strip excess characters from unquoted arguments
					} else if (unquoted
							&& rpseudo.test(unquoted)
							&&
							// Get excess from tokenize (recursively)
							(excess = tokenize(unquoted, true))
							&&
							// advance to the next closing parenthesis
							(excess = unquoted.indexOf(")", unquoted.length
									- excess)
									- unquoted.length)) {

						// excess is a negative index
						match[0] = match[0].slice(0, excess);
						match[2] = unquoted.slice(0, excess);
					}

					// Return only captures needed by the pseudo filter method
					// (type and argument)
					return match.slice(0, 3);
				}
			},

			filter : {

				"TAG" : function(nodeName) {
					if (nodeName === "*") {
						return function() {
							return true;
						};
					}

					nodeName = nodeName.replace(runescape, funescape)
							.toLowerCase();
					return function(elem) {
						return elem.nodeName
								&& elem.nodeName.toLowerCase() === nodeName;
					};
				},

				"CLASS" : function(className) {
					var pattern = classCache[className + " "];

					return pattern
							|| (pattern = new RegExp("(^|" + whitespace + ")"
									+ className + "(" + whitespace + "|$)"))
							&& classCache(
									className,
									function(elem) {
										return pattern
												.test(elem.className
														|| (typeof elem.getAttribute !== strundefined && elem
																.getAttribute("class"))
														|| "");
									});
				},

				"ATTR" : function(name, operator, check) {
					return function(elem) {
						var result = Sizzle.attr(elem, name);

						if (result == null) {
							return operator === "!=";
						}
						if (!operator) {
							return true;
						}

						result += "";

						return operator === "=" ? result === check
								: operator === "!=" ? result !== check
										: operator === "^=" ? check
												&& result.indexOf(check) === 0
												: operator === "*=" ? check
														&& result
																.indexOf(check) > -1
														: operator === "$=" ? check
																&& result
																		.slice(-check.length) === check
																: operator === "~=" ? (" "
																		+ result + " ")
																		.indexOf(check) > -1
																		: operator === "|=" ? result === check
																				|| result
																						.slice(
																								0,
																								check.length + 1) === check
																						+ "-"
																				: false;
					};
				},

				"CHILD" : function(type, what, argument, first, last) {
					var simple = type.slice(0, 3) !== "nth", forward = type
							.slice(-4) !== "last", ofType = what === "of-type";

					return first === 1 && last === 0 ?

					// Shortcut for :nth-*(n)
					function(elem) {
						return !!elem.parentNode;
					}
							:

							function(elem, context, xml) {
								var cache, outerCache, node, diff, nodeIndex, start, dir = simple !== forward ? "nextSibling"
										: "previousSibling", parent = elem.parentNode, name = ofType
										&& elem.nodeName.toLowerCase(), useCache = !xml
										&& !ofType;

								if (parent) {

									// :(first|last|only)-(child|of-type)
									if (simple) {
										while (dir) {
											node = elem;
											while ((node = node[dir])) {
												if (ofType ? node.nodeName
														.toLowerCase() === name
														: node.nodeType === 1) {
													return false;
												}
											}
											// Reverse direction for :only-* (if
											// we haven't yet done so)
											start = dir = type === "only"
													&& !start && "nextSibling";
										}
										return true;
									}

									start = [ forward ? parent.firstChild
											: parent.lastChild ];

									// non-xml :nth-child(...) stores cache data
									// on `parent`
									if (forward && useCache) {
										// Seek `elem` from a previously-cached
										// index
										outerCache = parent[expando]
												|| (parent[expando] = {});
										cache = outerCache[type] || [];
										nodeIndex = cache[0] === dirruns
												&& cache[1];
										diff = cache[0] === dirruns && cache[2];
										node = nodeIndex
												&& parent.childNodes[nodeIndex];

										while ((node = ++nodeIndex && node
												&& node[dir] ||

												// Fallback to seeking `elem`
												// from the start
												(diff = nodeIndex = 0)
												|| start.pop())) {

											// When found, cache indexes on
											// `parent` and break
											if (node.nodeType === 1 && ++diff
													&& node === elem) {
												outerCache[type] = [ dirruns,
														nodeIndex, diff ];
												break;
											}
										}

										// Use previously-cached element index
										// if available
									} else if (useCache
											&& (cache = (elem[expando] || (elem[expando] = {}))[type])
											&& cache[0] === dirruns) {
										diff = cache[1];

										// xml :nth-child(...) or
										// :nth-last-child(...) or
										// :nth(-last)?-of-type(...)
									} else {
										// Use the same loop as above to seek
										// `elem` from the start
										while ((node = ++nodeIndex && node
												&& node[dir]
												|| (diff = nodeIndex = 0)
												|| start.pop())) {

											if ((ofType ? node.nodeName
													.toLowerCase() === name
													: node.nodeType === 1)
													&& ++diff) {
												// Cache the index of each
												// encountered element
												if (useCache) {
													(node[expando] || (node[expando] = {}))[type] = [
															dirruns, diff ];
												}

												if (node === elem) {
													break;
												}
											}
										}
									}

									// Incorporate the offset, then check
									// against cycle size
									diff -= last;
									return diff === first
											|| (diff % first === 0 && diff
													/ first >= 0);
								}
							};
				},

				"PSEUDO" : function(pseudo, argument) {
					// pseudo-class names are case-insensitive
					// http://www.w3.org/TR/selectors/#pseudo-classes
					// Prioritize by case sensitivity in case custom pseudos are
					// added with uppercase letters
					// Remember that setFilters inherits from pseudos
					var args, fn = Expr.pseudos[pseudo]
							|| Expr.setFilters[pseudo.toLowerCase()]
							|| Sizzle.error("unsupported pseudo: " + pseudo);

					// The user may use createPseudo to indicate that
					// arguments are needed to create the filter function
					// just as Sizzle does
					if (fn[expando]) {
						return fn(argument);
					}

					// But maintain support for old signatures
					if (fn.length > 1) {
						args = [ pseudo, pseudo, "", argument ];
						return Expr.setFilters.hasOwnProperty(pseudo
								.toLowerCase()) ? markFunction(function(seed,
								matches) {
							var idx, matched = fn(seed, argument), i = matched.length;
							while (i--) {
								idx = indexOf.call(seed, matched[i]);
								seed[idx] = !(matches[idx] = matched[i]);
							}
						})
								: function(elem) {
									return fn(elem, 0, args);
								};
					}

					return fn;
				}
			},

			pseudos : {
				// Potentially complex pseudos
				"not" : markFunction(function(selector) {
					// Trim the selector passed to compile
					// to avoid treating leading and trailing
					// spaces as combinators
					var input = [], results = [], matcher = compile(selector
							.replace(rtrim, "$1"));

					return matcher[expando] ? markFunction(function(seed,
							matches, context, xml) {
						var elem, unmatched = matcher(seed, null, xml, []), i = seed.length;

						// Match elements unmatched by `matcher`
						while (i--) {
							if ((elem = unmatched[i])) {
								seed[i] = !(matches[i] = elem);
							}
						}
					})
							: function(elem, context, xml) {
								input[0] = elem;
								matcher(input, null, xml, results);
								return !results.pop();
							};
				}),

				"has" : markFunction(function(selector) {
					return function(elem) {
						return Sizzle(selector, elem).length > 0;
					};
				}),

				"contains" : markFunction(function(text) {
					return function(elem) {
						return (elem.textContent || elem.innerText || getText(elem))
								.indexOf(text) > -1;
					};
				}),

				// "Whether an element is represented by a :lang() selector
				// is based solely on the element's language value
				// being equal to the identifier C,
				// or beginning with the identifier C immediately followed by
				// "-".
				// The matching of C against the element's language value is
				// performed case-insensitively.
				// The identifier C does not have to be a valid language name."
				// http://www.w3.org/TR/selectors/#lang-pseudo
				"lang" : markFunction(function(lang) {
					// lang value must be a valid identifider
					if (!ridentifier.test(lang || "")) {
						Sizzle.error("unsupported lang: " + lang);
					}
					lang = lang.replace(runescape, funescape).toLowerCase();
					return function(elem) {
						var elemLang;
						do {
							if ((elemLang = documentIsXML ? elem
									.getAttribute("xml:lang")
									|| elem.getAttribute("lang") : elem.lang)) {

								elemLang = elemLang.toLowerCase();
								return elemLang === lang
										|| elemLang.indexOf(lang + "-") === 0;
							}
						} while ((elem = elem.parentNode)
								&& elem.nodeType === 1);
						return false;
					};
				}),

				// Miscellaneous
				"target" : function(elem) {
					var hash = window.location && window.location.hash;
					return hash && hash.slice(1) === elem.id;
				},

				"root" : function(elem) {
					return elem === docElem;
				},

				"focus" : function(elem) {
					return elem === document.activeElement
							&& (!document.hasFocus || document.hasFocus())
							&& !!(elem.type || elem.href || ~elem.tabIndex);
				},

				// Boolean properties
				"enabled" : function(elem) {
					return elem.disabled === false;
				},

				"disabled" : function(elem) {
					return elem.disabled === true;
				},

				"checked" : function(elem) {
					// In CSS3, :checked should return both checked and selected
					// elements
					// http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
					var nodeName = elem.nodeName.toLowerCase();
					return (nodeName === "input" && !!elem.checked)
							|| (nodeName === "option" && !!elem.selected);
				},

				"selected" : function(elem) {
					// Accessing this property makes selected-by-default
					// options in Safari work properly
					if (elem.parentNode) {
						elem.parentNode.selectedIndex;
					}

					return elem.selected === true;
				},

				// Contents
				"empty" : function(elem) {
					// http://www.w3.org/TR/selectors/#empty-pseudo
					// :empty is only affected by element nodes and content
					// nodes(including text(3), cdata(4)),
					// not comment, processing instructions, or others
					// Thanks to Diego Perini for the nodeName shortcut
					// Greater than "@" means alpha characters (specifically not
					// starting with "#" or "?")
					for (elem = elem.firstChild; elem; elem = elem.nextSibling) {
						if (elem.nodeName > "@" || elem.nodeType === 3
								|| elem.nodeType === 4) {
							return false;
						}
					}
					return true;
				},

				"parent" : function(elem) {
					return !Expr.pseudos["empty"](elem);
				},

				// Element/input types
				"header" : function(elem) {
					return rheader.test(elem.nodeName);
				},

				"input" : function(elem) {
					return rinputs.test(elem.nodeName);
				},

				"button" : function(elem) {
					var name = elem.nodeName.toLowerCase();
					return name === "input" && elem.type === "button"
							|| name === "button";
				},

				"text" : function(elem) {
					var attr;
					// IE6 and 7 will map elem.type to 'text' for new HTML5
					// types (search, etc)
					// use getAttribute instead to test this case
					return elem.nodeName.toLowerCase() === "input"
							&& elem.type === "text"
							&& ((attr = elem.getAttribute("type")) == null || attr
									.toLowerCase() === elem.type);
				},

				// Position-in-collection
				"first" : createPositionalPseudo(function() {
					return [ 0 ];
				}),

				"last" : createPositionalPseudo(function(matchIndexes, length) {
					return [ length - 1 ];
				}),

				"eq" : createPositionalPseudo(function(matchIndexes, length,
						argument) {
					return [ argument < 0 ? argument + length : argument ];
				}),

				"even" : createPositionalPseudo(function(matchIndexes, length) {
					var i = 0;
					for (; i < length; i += 2) {
						matchIndexes.push(i);
					}
					return matchIndexes;
				}),

				"odd" : createPositionalPseudo(function(matchIndexes, length) {
					var i = 1;
					for (; i < length; i += 2) {
						matchIndexes.push(i);
					}
					return matchIndexes;
				}),

				"lt" : createPositionalPseudo(function(matchIndexes, length,
						argument) {
					var i = argument < 0 ? argument + length : argument;
					for (; --i >= 0;) {
						matchIndexes.push(i);
					}
					return matchIndexes;
				}),

				"gt" : createPositionalPseudo(function(matchIndexes, length,
						argument) {
					var i = argument < 0 ? argument + length : argument;
					for (; ++i < length;) {
						matchIndexes.push(i);
					}
					return matchIndexes;
				})
			}
		};

		// Add button/input type pseudos
		for (i in {
			radio : true,
			checkbox : true,
			file : true,
			password : true,
			image : true
		}) {
			Expr.pseudos[i] = createInputPseudo(i);
		}
		for (i in {
			submit : true,
			reset : true
		}) {
			Expr.pseudos[i] = createButtonPseudo(i);
		}

		function tokenize(selector, parseOnly) {
			var matched, match, tokens, type, soFar, groups, preFilters, cached = tokenCache[selector
					+ " "];

			if (cached) {
				return parseOnly ? 0 : cached.slice(0);
			}

			soFar = selector;
			groups = [];
			preFilters = Expr.preFilter;

			while (soFar) {

				// Comma and first run
				if (!matched || (match = rcomma.exec(soFar))) {
					if (match) {
						// Don't consume trailing commas as valid
						soFar = soFar.slice(match[0].length) || soFar;
					}
					groups.push(tokens = []);
				}

				matched = false;

				// Combinators
				if ((match = rcombinators.exec(soFar))) {
					matched = match.shift();
					tokens.push({
						value : matched,
						// Cast descendant combinators to space
						type : match[0].replace(rtrim, " ")
					});
					soFar = soFar.slice(matched.length);
				}

				// Filters
				for (type in Expr.filter) {
					if ((match = matchExpr[type].exec(soFar))
							&& (!preFilters[type] || (match = preFilters[type]
									(match)))) {
						matched = match.shift();
						tokens.push({
							value : matched,
							type : type,
							matches : match
						});
						soFar = soFar.slice(matched.length);
					}
				}

				if (!matched) {
					break;
				}
			}

			// Return the length of the invalid excess
			// if we're just parsing
			// Otherwise, throw an error or return tokens
			return parseOnly ? soFar.length : soFar ? Sizzle.error(selector) :
			// Cache the tokens
			tokenCache(selector, groups).slice(0);
		}

		function toSelector(tokens) {
			var i = 0, len = tokens.length, selector = "";
			for (; i < len; i++) {
				selector += tokens[i].value;
			}
			return selector;
		}

		function addCombinator(matcher, combinator, base) {
			var dir = combinator.dir, checkNonElements = base
					&& dir === "parentNode", doneName = done++;

			return combinator.first ?
			// Check against closest ancestor/preceding element
			function(elem, context, xml) {
				while ((elem = elem[dir])) {
					if (elem.nodeType === 1 || checkNonElements) {
						return matcher(elem, context, xml);
					}
				}
			} :

			// Check against all ancestor/preceding elements
			function(elem, context, xml) {
				var data, cache, outerCache, dirkey = dirruns + " " + doneName;

				// We can't set arbitrary data on XML nodes, so they don't
				// benefit from dir caching
				if (xml) {
					while ((elem = elem[dir])) {
						if (elem.nodeType === 1 || checkNonElements) {
							if (matcher(elem, context, xml)) {
								return true;
							}
						}
					}
				} else {
					while ((elem = elem[dir])) {
						if (elem.nodeType === 1 || checkNonElements) {
							outerCache = elem[expando] || (elem[expando] = {});
							if ((cache = outerCache[dir])
									&& cache[0] === dirkey) {
								if ((data = cache[1]) === true
										|| data === cachedruns) {
									return data === true;
								}
							} else {
								cache = outerCache[dir] = [ dirkey ];
								cache[1] = matcher(elem, context, xml)
										|| cachedruns;
								if (cache[1] === true) {
									return true;
								}
							}
						}
					}
				}
			};
		}

		function elementMatcher(matchers) {
			return matchers.length > 1 ? function(elem, context, xml) {
				var i = matchers.length;
				while (i--) {
					if (!matchers[i](elem, context, xml)) {
						return false;
					}
				}
				return true;
			} : matchers[0];
		}

		function condense(unmatched, map, filter, context, xml) {
			var elem, newUnmatched = [], i = 0, len = unmatched.length, mapped = map != null;

			for (; i < len; i++) {
				if ((elem = unmatched[i])) {
					if (!filter || filter(elem, context, xml)) {
						newUnmatched.push(elem);
						if (mapped) {
							map.push(i);
						}
					}
				}
			}

			return newUnmatched;
		}

		function setMatcher(preFilter, selector, matcher, postFilter,
				postFinder, postSelector) {
			if (postFilter && !postFilter[expando]) {
				postFilter = setMatcher(postFilter);
			}
			if (postFinder && !postFinder[expando]) {
				postFinder = setMatcher(postFinder, postSelector);
			}
			return markFunction(function(seed, results, context, xml) {
				var temp, i, elem, preMap = [], postMap = [], preexisting = results.length,

				// Get initial elements from seed or context
				elems = seed
						|| multipleContexts(selector || "*",
								context.nodeType ? [ context ] : context, []),

				// Prefilter to get matcher input, preserving a map for
				// seed-results synchronization
				matcherIn = preFilter && (seed || !selector) ? condense(elems,
						preMap, preFilter, context, xml) : elems,

				matcherOut = matcher ?
				// If we have a postFinder, or filtered seed, or non-seed
				// postFilter or preexisting results,
				postFinder || (seed ? preFilter : preexisting || postFilter) ?

				// ...intermediate processing is necessary
				[] :

				// ...otherwise use results directly
				results : matcherIn;

				// Find primary matches
				if (matcher) {
					matcher(matcherIn, matcherOut, context, xml);
				}

				// Apply postFilter
				if (postFilter) {
					temp = condense(matcherOut, postMap);
					postFilter(temp, [], context, xml);

					// Un-match failing elements by moving them back to
					// matcherIn
					i = temp.length;
					while (i--) {
						if ((elem = temp[i])) {
							matcherOut[postMap[i]] = !(matcherIn[postMap[i]] = elem);
						}
					}
				}

				if (seed) {
					if (postFinder || preFilter) {
						if (postFinder) {
							// Get the final matcherOut by condensing this
							// intermediate into postFinder contexts
							temp = [];
							i = matcherOut.length;
							while (i--) {
								if ((elem = matcherOut[i])) {
									// Restore matcherIn since elem is not yet a
									// final match
									temp.push((matcherIn[i] = elem));
								}
							}
							postFinder(null, (matcherOut = []), temp, xml);
						}

						// Move matched elements from seed to results to keep
						// them synchronized
						i = matcherOut.length;
						while (i--) {
							if ((elem = matcherOut[i])
									&& (temp = postFinder ? indexOf.call(seed,
											elem) : preMap[i]) > -1) {

								seed[temp] = !(results[temp] = elem);
							}
						}
					}

					// Add elements to results, through postFinder if defined
				} else {
					matcherOut = condense(matcherOut === results ? matcherOut
							.splice(preexisting, matcherOut.length)
							: matcherOut);
					if (postFinder) {
						postFinder(null, results, matcherOut, xml);
					} else {
						push.apply(results, matcherOut);
					}
				}
			});
		}

		function matcherFromTokens(tokens) {
			var checkContext, matcher, j, len = tokens.length, leadingRelative = Expr.relative[tokens[0].type], implicitRelative = leadingRelative
					|| Expr.relative[" "], i = leadingRelative ? 1 : 0,

			// The foundational matcher ensures that elements are reachable from
			// top-level context(s)
			matchContext = addCombinator(function(elem) {
				return elem === checkContext;
			}, implicitRelative, true), matchAnyContext = addCombinator(
					function(elem) {
						return indexOf.call(checkContext, elem) > -1;
					}, implicitRelative, true), matchers = [ function(elem,
					context, xml) {
				return (!leadingRelative && (xml || context !== outermostContext))
						|| ((checkContext = context).nodeType ? matchContext(
								elem, context, xml) : matchAnyContext(elem,
								context, xml));
			} ];

			for (; i < len; i++) {
				if ((matcher = Expr.relative[tokens[i].type])) {
					matchers = [ addCombinator(elementMatcher(matchers),
							matcher) ];
				} else {
					matcher = Expr.filter[tokens[i].type].apply(null,
							tokens[i].matches);

					// Return special upon seeing a positional matcher
					if (matcher[expando]) {
						// Find the next relative operator (if any) for proper
						// handling
						j = ++i;
						for (; j < len; j++) {
							if (Expr.relative[tokens[j].type]) {
								break;
							}
						}
						return setMatcher(i > 1 && elementMatcher(matchers),
								i > 1
										&& toSelector(tokens.slice(0, i - 1))
												.replace(rtrim, "$1"), matcher,
								i < j && matcherFromTokens(tokens.slice(i, j)),
								j < len
										&& matcherFromTokens((tokens = tokens
												.slice(j))), j < len
										&& toSelector(tokens));
					}
					matchers.push(matcher);
				}
			}

			return elementMatcher(matchers);
		}

		function matcherFromGroupMatchers(elementMatchers, setMatchers) {
			// A counter to specify which element is currently being matched
			var matcherCachedRuns = 0, bySet = setMatchers.length > 0, byElement = elementMatchers.length > 0, superMatcher = function(
					seed, context, xml, results, expandContext) {
				var elem, j, matcher, setMatched = [], matchedCount = 0, i = "0", unmatched = seed
						&& [], outermost = expandContext != null, contextBackup = outermostContext,
				// We must always have either seed elements or context
				elems = seed
						|| byElement
						&& Expr.find["TAG"]("*", expandContext
								&& context.parentNode || context),
				// Use integer dirruns iff this is the outermost matcher
				dirrunsUnique = (dirruns += contextBackup == null ? 1 : Math
						.random() || 0.1);

				if (outermost) {
					outermostContext = context !== document && context;
					cachedruns = matcherCachedRuns;
				}

				// Add elements passing elementMatchers directly to results
				// Keep `i` a string if there are no elements so `matchedCount`
				// will be "00" below
				for (; (elem = elems[i]) != null; i++) {
					if (byElement && elem) {
						j = 0;
						while ((matcher = elementMatchers[j++])) {
							if (matcher(elem, context, xml)) {
								results.push(elem);
								break;
							}
						}
						if (outermost) {
							dirruns = dirrunsUnique;
							cachedruns = ++matcherCachedRuns;
						}
					}

					// Track unmatched elements for set filters
					if (bySet) {
						// They will have gone through all possible matchers
						if ((elem = !matcher && elem)) {
							matchedCount--;
						}

						// Lengthen the array for every element, matched or not
						if (seed) {
							unmatched.push(elem);
						}
					}
				}

				// Apply set filters to unmatched elements
				matchedCount += i;
				if (bySet && i !== matchedCount) {
					j = 0;
					while ((matcher = setMatchers[j++])) {
						matcher(unmatched, setMatched, context, xml);
					}

					if (seed) {
						// Reintegrate element matches to eliminate the need for
						// sorting
						if (matchedCount > 0) {
							while (i--) {
								if (!(unmatched[i] || setMatched[i])) {
									setMatched[i] = pop.call(results);
								}
							}
						}

						// Discard index placeholder values to get only actual
						// matches
						setMatched = condense(setMatched);
					}

					// Add matches to results
					push.apply(results, setMatched);

					// Seedless set matches succeeding multiple successful
					// matchers stipulate sorting
					if (outermost && !seed && setMatched.length > 0
							&& (matchedCount + setMatchers.length) > 1) {

						Sizzle.uniqueSort(results);
					}
				}

				// Override manipulation of globals by nested matchers
				if (outermost) {
					dirruns = dirrunsUnique;
					outermostContext = contextBackup;
				}

				return unmatched;
			};

			return bySet ? markFunction(superMatcher) : superMatcher;
		}

		compile = Sizzle.compile = function(selector, group /* Internal Use Only */) {
			var i, setMatchers = [], elementMatchers = [], cached = compilerCache[selector
					+ " "];

			if (!cached) {
				// Generate a function of recursive functions that can be used
				// to check each element
				if (!group) {
					group = tokenize(selector);
				}
				i = group.length;
				while (i--) {
					cached = matcherFromTokens(group[i]);
					if (cached[expando]) {
						setMatchers.push(cached);
					} else {
						elementMatchers.push(cached);
					}
				}

				// Cache the compiled function
				cached = compilerCache(selector, matcherFromGroupMatchers(
						elementMatchers, setMatchers));
			}
			return cached;
		};

		function multipleContexts(selector, contexts, results) {
			var i = 0, len = contexts.length;
			for (; i < len; i++) {
				Sizzle(selector, contexts[i], results);
			}
			return results;
		}

		function select(selector, context, results, seed) {
			var i, tokens, token, type, find, match = tokenize(selector);

			if (!seed) {
				// Try to minimize operations if there is only one group
				if (match.length === 1) {

					// Take a shortcut and set the context if the root selector
					// is an ID
					tokens = match[0] = match[0].slice(0);
					if (tokens.length > 2 && (token = tokens[0]).type === "ID"
							&& context.nodeType === 9 && !documentIsXML
							&& Expr.relative[tokens[1].type]) {

						context = Expr.find["ID"](token.matches[0].replace(
								runescape, funescape), context)[0];
						if (!context) {
							return results;
						}

						selector = selector.slice(tokens.shift().value.length);
					}

					// Fetch a seed set for right-to-left matching
					i = matchExpr["needsContext"].test(selector) ? 0
							: tokens.length;
					while (i--) {
						token = tokens[i];

						// Abort if we hit a combinator
						if (Expr.relative[(type = token.type)]) {
							break;
						}
						if ((find = Expr.find[type])) {
							// Search, expanding context for leading sibling
							// combinators
							if ((seed = find(token.matches[0].replace(
									runescape, funescape), rsibling
									.test(tokens[0].type)
									&& context.parentNode || context))) {

								// If seed is empty or no tokens remain, we can
								// return early
								tokens.splice(i, 1);
								selector = seed.length && toSelector(tokens);
								if (!selector) {
									push.apply(results, slice.call(seed, 0));
									return results;
								}

								break;
							}
						}
					}
				}
			}

			// Compile and execute a filtering function
			// Provide `match` to avoid retokenization if we modified the
			// selector above
			compile(selector, match)(seed, context, documentIsXML, results,
					rsibling.test(selector));
			return results;
		}

		// Deprecated
		Expr.pseudos["nth"] = Expr.pseudos["eq"];

		// Easy API for creating new setFilters
		function setFilters() {
		}
		Expr.filters = setFilters.prototype = Expr.pseudos;
		Expr.setFilters = new setFilters();

		// Initialize with the default document
		setDocument();

		// Override sizzle attribute retrieval
		Sizzle.attr = jQuery.attr;
		jQuery.find = Sizzle;
		jQuery.expr = Sizzle.selectors;
		jQuery.expr[":"] = jQuery.expr.pseudos;
		jQuery.unique = Sizzle.uniqueSort;
		jQuery.text = Sizzle.getText;
		jQuery.isXMLDoc = Sizzle.isXML;
		jQuery.contains = Sizzle.contains;

	})(window);
	var runtil = /Until$/, rparentsprev = /^(?:parents|prev(?:Until|All))/, isSimple = /^.[^:#\[\.,]*$/, rneedsContext = jQuery.expr.match.needsContext,
	// methods guaranteed to produce a unique set when starting from a unique
	// set
	guaranteedUnique = {
		children : true,
		contents : true,
		next : true,
		prev : true
	};

	jQuery.fn
			.extend({
				find : function(selector) {
					var i, ret, self, len = this.length;

					if (typeof selector !== "string") {
						self = this;
						return this.pushStack(jQuery(selector).filter(
								function() {
									for (i = 0; i < len; i++) {
										if (jQuery.contains(self[i], this)) {
											return true;
										}
									}
								}));
					}

					ret = [];
					for (i = 0; i < len; i++) {
						jQuery.find(selector, this[i], ret);
					}

					// Needed because $( selector, context ) becomes $( context
					// ).find( selector )
					ret = this.pushStack(len > 1 ? jQuery.unique(ret) : ret);
					ret.selector = (this.selector ? this.selector + " " : "")
							+ selector;
					return ret;
				},

				has : function(target) {
					var i, targets = jQuery(target, this), len = targets.length;

					return this.filter(function() {
						for (i = 0; i < len; i++) {
							if (jQuery.contains(this, targets[i])) {
								return true;
							}
						}
					});
				},

				not : function(selector) {
					return this.pushStack(winnow(this, selector, false));
				},

				filter : function(selector) {
					return this.pushStack(winnow(this, selector, true));
				},

				is : function(selector) {
					return !!selector
							&& (typeof selector === "string" ?
							// If this is a positional/relative selector, check
							// membership in the returned set
							// so $("p:first").is("p:last") won't return true
							// for a doc with two "p".
							rneedsContext.test(selector) ? jQuery(selector,
									this.context).index(this[0]) >= 0 : jQuery
									.filter(selector, this).length > 0 : this
									.filter(selector).length > 0);
				},

				closest : function(selectors, context) {
					var cur, i = 0, l = this.length, ret = [], pos = rneedsContext
							.test(selectors)
							|| typeof selectors !== "string" ? jQuery(
							selectors, context || this.context) : 0;

					for (; i < l; i++) {
						cur = this[i];

						while (cur && cur.ownerDocument && cur !== context
								&& cur.nodeType !== 11) {
							if (pos ? pos.index(cur) > -1 : jQuery.find
									.matchesSelector(cur, selectors)) {
								ret.push(cur);
								break;
							}
							cur = cur.parentNode;
						}
					}

					return this.pushStack(ret.length > 1 ? jQuery.unique(ret)
							: ret);
				},

				// Determine the position of an element within
				// the matched set of elements
				index : function(elem) {

					// No argument, return index in parent
					if (!elem) {
						return (this[0] && this[0].parentNode) ? this.first()
								.prevAll().length : -1;
					}

					// index in selector
					if (typeof elem === "string") {
						return jQuery.inArray(this[0], jQuery(elem));
					}

					// Locate the position of the desired element
					return jQuery.inArray(
					// If it receives a jQuery object, the first element is used
					elem.jquery ? elem[0] : elem, this);
				},

				add : function(selector, context) {
					var set = typeof selector === "string" ? jQuery(selector,
							context) : jQuery.makeArray(selector
							&& selector.nodeType ? [ selector ] : selector), all = jQuery
							.merge(this.get(), set);

					return this.pushStack(jQuery.unique(all));
				},

				addBack : function(selector) {
					return this.add(selector == null ? this.prevObject
							: this.prevObject.filter(selector));
				}
			});

	jQuery.fn.andSelf = jQuery.fn.addBack;

	function sibling(cur, dir) {
		do {
			cur = cur[dir];
		} while (cur && cur.nodeType !== 1);

		return cur;
	}

	jQuery.each({
		parent : function(elem) {
			var parent = elem.parentNode;
			return parent && parent.nodeType !== 11 ? parent : null;
		},
		parents : function(elem) {
			return jQuery.dir(elem, "parentNode");
		},
		parentsUntil : function(elem, i, until) {
			return jQuery.dir(elem, "parentNode", until);
		},
		next : function(elem) {
			return sibling(elem, "nextSibling");
		},
		prev : function(elem) {
			return sibling(elem, "previousSibling");
		},
		nextAll : function(elem) {
			return jQuery.dir(elem, "nextSibling");
		},
		prevAll : function(elem) {
			return jQuery.dir(elem, "previousSibling");
		},
		nextUntil : function(elem, i, until) {
			return jQuery.dir(elem, "nextSibling", until);
		},
		prevUntil : function(elem, i, until) {
			return jQuery.dir(elem, "previousSibling", until);
		},
		siblings : function(elem) {
			return jQuery.sibling((elem.parentNode || {}).firstChild, elem);
		},
		children : function(elem) {
			return jQuery.sibling(elem.firstChild);
		},
		contents : function(elem) {
			return jQuery.nodeName(elem, "iframe") ? elem.contentDocument
					|| elem.contentWindow.document : jQuery.merge([],
					elem.childNodes);
		}
	}, function(name, fn) {
		jQuery.fn[name] = function(until, selector) {
			var ret = jQuery.map(this, fn, until);

			if (!runtil.test(name)) {
				selector = until;
			}

			if (selector && typeof selector === "string") {
				ret = jQuery.filter(selector, ret);
			}

			ret = this.length > 1 && !guaranteedUnique[name] ? jQuery
					.unique(ret) : ret;

			if (this.length > 1 && rparentsprev.test(name)) {
				ret = ret.reverse();
			}

			return this.pushStack(ret);
		};
	});

	jQuery.extend({
		filter : function(expr, elems, not) {
			if (not) {
				expr = ":not(" + expr + ")";
			}

			return elems.length === 1 ? jQuery.find.matchesSelector(elems[0],
					expr) ? [ elems[0] ] : [] : jQuery.find
					.matches(expr, elems);
		},

		dir : function(elem, dir, until) {
			var matched = [], cur = elem[dir];

			while (cur
					&& cur.nodeType !== 9
					&& (until === undefined || cur.nodeType !== 1 || !jQuery(
							cur).is(until))) {
				if (cur.nodeType === 1) {
					matched.push(cur);
				}
				cur = cur[dir];
			}
			return matched;
		},

		sibling : function(n, elem) {
			var r = [];

			for (; n; n = n.nextSibling) {
				if (n.nodeType === 1 && n !== elem) {
					r.push(n);
				}
			}

			return r;
		}
	});

	// Implement the identical functionality for filter and not
	function winnow(elements, qualifier, keep) {

		// Can't pass null or undefined to indexOf in Firefox 4
		// Set to 0 to skip string check
		qualifier = qualifier || 0;

		if (jQuery.isFunction(qualifier)) {
			return jQuery.grep(elements, function(elem, i) {
				var retVal = !!qualifier.call(elem, i, elem);
				return retVal === keep;
			});

		} else if (qualifier.nodeType) {
			return jQuery.grep(elements, function(elem) {
				return (elem === qualifier) === keep;
			});

		} else if (typeof qualifier === "string") {
			var filtered = jQuery.grep(elements, function(elem) {
				return elem.nodeType === 1;
			});

			if (isSimple.test(qualifier)) {
				return jQuery.filter(qualifier, filtered, !keep);
			} else {
				qualifier = jQuery.filter(qualifier, filtered);
			}
		}

		return jQuery.grep(elements, function(elem) {
			return (jQuery.inArray(elem, qualifier) >= 0) === keep;
		});
	}
	function createSafeFragment(document) {
		var list = nodeNames.split("|"), safeFrag = document
				.createDocumentFragment();

		if (safeFrag.createElement) {
			while (list.length) {
				safeFrag.createElement(list.pop());
			}
		}
		return safeFrag;
	}

	var nodeNames = "abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|"
			+ "header|hgroup|mark|meter|nav|output|progress|section|summary|time|video", rinlinejQuery = / jQuery\d+="(?:null|\d+)"/g, rnoshimcache = new RegExp(
			"<(?:" + nodeNames + ")[\\s/>]", "i"), rleadingWhitespace = /^\s+/, rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi, rtagName = /<([\w:]+)/, rtbody = /<tbody/i, rhtml = /<|&#?\w+;/, rnoInnerhtml = /<(?:script|style|link)/i, manipulation_rcheckableType = /^(?:checkbox|radio)$/i,
	// checked="checked" or checked
	rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i, rscriptType = /^$|\/(?:java|ecma)script/i, rscriptTypeMasked = /^true\/(.*)/, rcleanScript = /^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g,

	// We have to close these tags to support XHTML (#13200)
	wrapMap = {
		option : [ 1, "<select multiple='multiple'>", "</select>" ],
		legend : [ 1, "<fieldset>", "</fieldset>" ],
		area : [ 1, "<map>", "</map>" ],
		param : [ 1, "<object>", "</object>" ],
		thead : [ 1, "<table>", "</table>" ],
		tr : [ 2, "<table><tbody>", "</tbody></table>" ],
		col : [ 2, "<table><tbody></tbody><colgroup>", "</colgroup></table>" ],
		td : [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ],

		// IE6-8 can't serialize link, script, style, or any html5 (NoScope)
		// tags,
		// unless wrapped in a div with non-breaking characters in front of it.
		_default : jQuery.support.htmlSerialize ? [ 0, "", "" ] : [ 1,
				"X<div>", "</div>" ]
	}, safeFragment = createSafeFragment(document), fragmentDiv = safeFragment
			.appendChild(document.createElement("div"));

	wrapMap.optgroup = wrapMap.option;
	wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;
	wrapMap.th = wrapMap.td;

	jQuery.fn
			.extend({
				text : function(value) {
					return jQuery
							.access(
									this,
									function(value) {
										return value === undefined ? jQuery
												.text(this)
												: this
														.empty()
														.append(
																(this[0]
																		&& this[0].ownerDocument || document)
																		.createTextNode(value));
									}, null, value, arguments.length);
				},

				wrapAll : function(html) {
					if (jQuery.isFunction(html)) {
						return this.each(function(i) {
							jQuery(this).wrapAll(html.call(this, i));
						});
					}

					if (this[0]) {
						// The elements to wrap the target around
						var wrap = jQuery(html, this[0].ownerDocument).eq(0)
								.clone(true);

						if (this[0].parentNode) {
							wrap.insertBefore(this[0]);
						}

						wrap.map(
								function() {
									var elem = this;

									while (elem.firstChild
											&& elem.firstChild.nodeType === 1) {
										elem = elem.firstChild;
									}

									return elem;
								}).append(this);
					}

					return this;
				},

				wrapInner : function(html) {
					if (jQuery.isFunction(html)) {
						return this.each(function(i) {
							jQuery(this).wrapInner(html.call(this, i));
						});
					}

					return this.each(function() {
						var self = jQuery(this), contents = self.contents();

						if (contents.length) {
							contents.wrapAll(html);

						} else {
							self.append(html);
						}
					});
				},

				wrap : function(html) {
					var isFunction = jQuery.isFunction(html);

					return this.each(function(i) {
						jQuery(this).wrapAll(
								isFunction ? html.call(this, i) : html);
					});
				},

				unwrap : function() {
					return this.parent().each(function() {
						if (!jQuery.nodeName(this, "body")) {
							jQuery(this).replaceWith(this.childNodes);
						}
					}).end();
				},

				append : function() {
					return this.domManip(arguments, true, function(elem) {
						if (this.nodeType === 1 || this.nodeType === 11
								|| this.nodeType === 9) {
							this.appendChild(elem);
						}
					});
				},

				prepend : function() {
					return this.domManip(arguments, true, function(elem) {
						if (this.nodeType === 1 || this.nodeType === 11
								|| this.nodeType === 9) {
							this.insertBefore(elem, this.firstChild);
						}
					});
				},

				before : function() {
					return this.domManip(arguments, false, function(elem) {
						if (this.parentNode) {
							this.parentNode.insertBefore(elem, this);
						}
					});
				},

				after : function() {
					return this.domManip(arguments, false, function(elem) {
						if (this.parentNode) {
							this.parentNode
									.insertBefore(elem, this.nextSibling);
						}
					});
				},

				// keepData is for internal use only--do not document
				remove : function(selector, keepData) {
					var elem, i = 0;

					for (; (elem = this[i]) != null; i++) {
						if (!selector
								|| jQuery.filter(selector, [ elem ]).length > 0) {
							if (!keepData && elem.nodeType === 1) {
								jQuery.cleanData(getAll(elem));
							}

							if (elem.parentNode) {
								if (keepData
										&& jQuery.contains(elem.ownerDocument,
												elem)) {
									setGlobalEval(getAll(elem, "script"));
								}
								elem.parentNode.removeChild(elem);
							}
						}
					}

					return this;
				},

				empty : function() {
					var elem, i = 0;

					for (; (elem = this[i]) != null; i++) {
						// Remove element nodes and prevent memory leaks
						if (elem.nodeType === 1) {
							jQuery.cleanData(getAll(elem, false));
						}

						// Remove any remaining nodes
						while (elem.firstChild) {
							elem.removeChild(elem.firstChild);
						}

						// If this is a select, ensure that it displays empty
						// (#12336)
						// Support: IE<9
						if (elem.options && jQuery.nodeName(elem, "select")) {
							elem.options.length = 0;
						}
					}

					return this;
				},

				clone : function(dataAndEvents, deepDataAndEvents) {
					dataAndEvents = dataAndEvents == null ? false
							: dataAndEvents;
					deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents
							: deepDataAndEvents;

					return this.map(function() {
						return jQuery.clone(this, dataAndEvents,
								deepDataAndEvents);
					});
				},

				html : function(value) {
					return jQuery
							.access(
									this,
									function(value) {
										var elem = this[0] || {}, i = 0, l = this.length;

										if (value === undefined) {
											return elem.nodeType === 1 ? elem.innerHTML
													.replace(rinlinejQuery, "")
													: undefined;
										}

										// See if we can take a shortcut and
										// just use innerHTML
										if (typeof value === "string"
												&& !rnoInnerhtml.test(value)
												&& (jQuery.support.htmlSerialize || !rnoshimcache
														.test(value))
												&& (jQuery.support.leadingWhitespace || !rleadingWhitespace
														.test(value))
												&& !wrapMap[(rtagName
														.exec(value) || [ "",
														"" ])[1].toLowerCase()]) {

											value = value.replace(rxhtmlTag,
													"<$1></$2>");

											try {
												for (; i < l; i++) {
													// Remove element nodes and
													// prevent memory leaks
													elem = this[i] || {};
													if (elem.nodeType === 1) {
														jQuery
																.cleanData(getAll(
																		elem,
																		false));
														elem.innerHTML = value;
													}
												}

												elem = 0;

												// If using innerHTML throws an
												// exception, use the fallback
												// method
											} catch (e) {
											}
										}

										if (elem) {
											this.empty().append(value);
										}
									}, null, value, arguments.length);
				},

				replaceWith : function(value) {
					var isFunc = jQuery.isFunction(value);

					// Make sure that the elements are removed from the DOM
					// before they are inserted
					// this can help fix replacing a parent with child elements
					if (!isFunc && typeof value !== "string") {
						value = jQuery(value).not(this).detach();
					}

					return this.domManip([ value ], true, function(elem) {
						var next = this.nextSibling, parent = this.parentNode;

						if (parent) {
							jQuery(this).remove();
							parent.insertBefore(elem, next);
						}
					});
				},

				detach : function(selector) {
					return this.remove(selector, true);
				},

				domManip : function(args, table, callback) {

					// Flatten any nested arrays
					args = core_concat.apply([], args);

					var first, node, hasScripts, scripts, doc, fragment, i = 0, l = this.length, set = this, iNoClone = l - 1, value = args[0], isFunction = jQuery
							.isFunction(value);

					// We can't cloneNode fragments that contain checked, in
					// WebKit
					if (isFunction
							|| !(l <= 1 || typeof value !== "string"
									|| jQuery.support.checkClone || !rchecked
									.test(value))) {
						return this.each(function(index) {
							var self = set.eq(index);
							if (isFunction) {
								args[0] = value.call(this, index, table ? self
										.html() : undefined);
							}
							self.domManip(args, table, callback);
						});
					}

					if (l) {
						fragment = jQuery.buildFragment(args,
								this[0].ownerDocument, false, this);
						first = fragment.firstChild;

						if (fragment.childNodes.length === 1) {
							fragment = first;
						}

						if (first) {
							table = table && jQuery.nodeName(first, "tr");
							scripts = jQuery.map(getAll(fragment, "script"),
									disableScript);
							hasScripts = scripts.length;

							// Use the original fragment for the last item
							// instead of the first because it can end up
							// being emptied incorrectly in certain situations
							// (#8070).
							for (; i < l; i++) {
								node = fragment;

								if (i !== iNoClone) {
									node = jQuery.clone(node, true, true);

									// Keep references to cloned scripts for
									// later restoration
									if (hasScripts) {
										jQuery.merge(scripts, getAll(node,
												"script"));
									}
								}

								callback
										.call(
												table
														&& jQuery.nodeName(
																this[i],
																"table") ? findOrAppend(
														this[i], "tbody")
														: this[i], node, i);
							}

							if (hasScripts) {
								doc = scripts[scripts.length - 1].ownerDocument;

								// Reenable scripts
								jQuery.map(scripts, restoreScript);

								// Evaluate executable scripts on first document
								// insertion
								for (i = 0; i < hasScripts; i++) {
									node = scripts[i];
									if (rscriptType.test(node.type || "")
											&& !jQuery
													._data(node, "globalEval")
											&& jQuery.contains(doc, node)) {

										if (node.src) {
											// Hope ajax is available...
											jQuery.ajax({
												url : node.src,
												type : "GET",
												dataType : "script",
												async : false,
												global : false,
												"throws" : true
											});
										} else {
											jQuery.globalEval((node.text
													|| node.textContent
													|| node.innerHTML || "")
													.replace(rcleanScript, ""));
										}
									}
								}
							}

							// Fix #11809: Avoid leaking memory
							fragment = first = null;
						}
					}

					return this;
				}
			});

	function findOrAppend(elem, tag) {
		return elem.getElementsByTagName(tag)[0]
				|| elem.appendChild(elem.ownerDocument.createElement(tag));
	}

	// Replace/restore the type attribute of script elements for safe DOM
	// manipulation
	function disableScript(elem) {
		var attr = elem.getAttributeNode("type");
		elem.type = (attr && attr.specified) + "/" + elem.type;
		return elem;
	}
	function restoreScript(elem) {
		var match = rscriptTypeMasked.exec(elem.type);
		if (match) {
			elem.type = match[1];
		} else {
			elem.removeAttribute("type");
		}
		return elem;
	}

	// Mark scripts as having already been evaluated
	function setGlobalEval(elems, refElements) {
		var elem, i = 0;
		for (; (elem = elems[i]) != null; i++) {
			jQuery._data(elem, "globalEval", !refElements
					|| jQuery._data(refElements[i], "globalEval"));
		}
	}

	function cloneCopyEvent(src, dest) {

		if (dest.nodeType !== 1 || !jQuery.hasData(src)) {
			return;
		}

		var type, i, l, oldData = jQuery._data(src), curData = jQuery._data(
				dest, oldData), events = oldData.events;

		if (events) {
			delete curData.handle;
			curData.events = {};

			for (type in events) {
				for (i = 0, l = events[type].length; i < l; i++) {
					jQuery.event.add(dest, type, events[type][i]);
				}
			}
		}

		// make the cloned public data object a copy from the original
		if (curData.data) {
			curData.data = jQuery.extend({}, curData.data);
		}
	}

	function fixCloneNodeIssues(src, dest) {
		var nodeName, e, data;

		// We do not need to do anything for non-Elements
		if (dest.nodeType !== 1) {
			return;
		}

		nodeName = dest.nodeName.toLowerCase();

		// IE6-8 copies events bound via attachEvent when using cloneNode.
		if (!jQuery.support.noCloneEvent && dest[jQuery.expando]) {
			data = jQuery._data(dest);

			for (e in data.events) {
				jQuery.removeEvent(dest, e, data.handle);
			}

			// Event data gets referenced instead of copied if the expando gets
			// copied too
			dest.removeAttribute(jQuery.expando);
		}

		// IE blanks contents when cloning scripts, and tries to evaluate
		// newly-set text
		if (nodeName === "script" && dest.text !== src.text) {
			disableScript(dest).text = src.text;
			restoreScript(dest);

			// IE6-10 improperly clones children of object elements using
			// classid.
			// IE10 throws NoModificationAllowedError if parent is null, #12132.
		} else if (nodeName === "object") {
			if (dest.parentNode) {
				dest.outerHTML = src.outerHTML;
			}

			// This path appears unavoidable for IE9. When cloning an object
			// element in IE9, the outerHTML strategy above is not sufficient.
			// If the src has innerHTML and the destination does not,
			// copy the src.innerHTML into the dest.innerHTML. #10324
			if (jQuery.support.html5Clone
					&& (src.innerHTML && !jQuery.trim(dest.innerHTML))) {
				dest.innerHTML = src.innerHTML;
			}

		} else if (nodeName === "input"
				&& manipulation_rcheckableType.test(src.type)) {
			// IE6-8 fails to persist the checked state of a cloned checkbox
			// or radio button. Worse, IE6-7 fail to give the cloned element
			// a checked appearance if the defaultChecked value isn't also set

			dest.defaultChecked = dest.checked = src.checked;

			// IE6-7 get confused and end up setting the value of a cloned
			// checkbox/radio button to an empty string instead of "on"
			if (dest.value !== src.value) {
				dest.value = src.value;
			}

			// IE6-8 fails to return the selected option to the default selected
			// state when cloning options
		} else if (nodeName === "option") {
			dest.defaultSelected = dest.selected = src.defaultSelected;

			// IE6-8 fails to set the defaultValue to the correct value when
			// cloning other types of input fields
		} else if (nodeName === "input" || nodeName === "textarea") {
			dest.defaultValue = src.defaultValue;
		}
	}

	jQuery
			.each(
					{
						appendTo : "append",
						prependTo : "prepend",
						insertBefore : "before",
						insertAfter : "after",
						replaceAll : "replaceWith"
					},
					function(name, original) {
						jQuery.fn[name] = function(selector) {
							var elems, i = 0, ret = [], insert = jQuery(selector), last = insert.length - 1;

							for (; i <= last; i++) {
								elems = i === last ? this : this.clone(true);
								jQuery(insert[i])[original](elems);

								// Modern browsers can apply jQuery collections
								// as arrays, but oldIE needs a .get()
								core_push.apply(ret, elems.get());
							}

							return this.pushStack(ret);
						};
					});

	function getAll(context, tag) {
		var elems, elem, i = 0, found = typeof context.getElementsByTagName !== core_strundefined ? context
				.getElementsByTagName(tag || "*")
				: typeof context.querySelectorAll !== core_strundefined ? context
						.querySelectorAll(tag || "*")
						: undefined;

		if (!found) {
			for (found = [], elems = context.childNodes || context; (elem = elems[i]) != null; i++) {
				if (!tag || jQuery.nodeName(elem, tag)) {
					found.push(elem);
				} else {
					jQuery.merge(found, getAll(elem, tag));
				}
			}
		}

		return tag === undefined || tag && jQuery.nodeName(context, tag) ? jQuery
				.merge([ context ], found)
				: found;
	}

	// Used in buildFragment, fixes the defaultChecked property
	function fixDefaultChecked(elem) {
		if (manipulation_rcheckableType.test(elem.type)) {
			elem.defaultChecked = elem.checked;
		}
	}

	jQuery
			.extend({
				clone : function(elem, dataAndEvents, deepDataAndEvents) {
					var destElements, node, clone, i, srcElements, inPage = jQuery
							.contains(elem.ownerDocument, elem);

					if (jQuery.support.html5Clone || jQuery.isXMLDoc(elem)
							|| !rnoshimcache.test("<" + elem.nodeName + ">")) {
						clone = elem.cloneNode(true);

						// IE<=8 does not properly clone detached, unknown
						// element nodes
					} else {
						fragmentDiv.innerHTML = elem.outerHTML;
						fragmentDiv.removeChild(clone = fragmentDiv.firstChild);
					}

					if ((!jQuery.support.noCloneEvent || !jQuery.support.noCloneChecked)
							&& (elem.nodeType === 1 || elem.nodeType === 11)
							&& !jQuery.isXMLDoc(elem)) {

						// We eschew Sizzle here for performance reasons:
						// http://jsperf.com/getall-vs-sizzle/2
						destElements = getAll(clone);
						srcElements = getAll(elem);

						// Fix all IE cloning issues
						for (i = 0; (node = srcElements[i]) != null; ++i) {
							// Ensure that the destination node is not null;
							// Fixes #9587
							if (destElements[i]) {
								fixCloneNodeIssues(node, destElements[i]);
							}
						}
					}

					// Copy the events from the original to the clone
					if (dataAndEvents) {
						if (deepDataAndEvents) {
							srcElements = srcElements || getAll(elem);
							destElements = destElements || getAll(clone);

							for (i = 0; (node = srcElements[i]) != null; i++) {
								cloneCopyEvent(node, destElements[i]);
							}
						} else {
							cloneCopyEvent(elem, clone);
						}
					}

					// Preserve script evaluation history
					destElements = getAll(clone, "script");
					if (destElements.length > 0) {
						setGlobalEval(destElements, !inPage
								&& getAll(elem, "script"));
					}

					destElements = srcElements = node = null;

					// Return the cloned set
					return clone;
				},

				buildFragment : function(elems, context, scripts, selection) {
					var j, elem, contains, tmp, tag, tbody, wrap, l = elems.length,

					// Ensure a safe fragment
					safe = createSafeFragment(context),

					nodes = [], i = 0;

					for (; i < l; i++) {
						elem = elems[i];

						if (elem || elem === 0) {

							// Add nodes directly
							if (jQuery.type(elem) === "object") {
								jQuery.merge(nodes, elem.nodeType ? [ elem ]
										: elem);

								// Convert non-html into a text node
							} else if (!rhtml.test(elem)) {
								nodes.push(context.createTextNode(elem));

								// Convert html into DOM nodes
							} else {
								tmp = tmp
										|| safe.appendChild(context
												.createElement("div"));

								// Deserialize a standard representation
								tag = (rtagName.exec(elem) || [ "", "" ])[1]
										.toLowerCase();
								wrap = wrapMap[tag] || wrapMap._default;

								tmp.innerHTML = wrap[1]
										+ elem.replace(rxhtmlTag, "<$1></$2>")
										+ wrap[2];

								// Descend through wrappers to the right content
								j = wrap[0];
								while (j--) {
									tmp = tmp.lastChild;
								}

								// Manually add leading whitespace removed by IE
								if (!jQuery.support.leadingWhitespace
										&& rleadingWhitespace.test(elem)) {
									nodes.push(context
											.createTextNode(rleadingWhitespace
													.exec(elem)[0]));
								}

								// Remove IE's autoinserted <tbody> from table
								// fragments
								if (!jQuery.support.tbody) {

									// String was a <table>, *may* have spurious
									// <tbody>
									elem = tag === "table"
											&& !rtbody.test(elem) ? tmp.firstChild
											:

											// String was a bare <thead> or
											// <tfoot>
											wrap[1] === "<table>"
													&& !rtbody.test(elem) ? tmp
													: 0;

									j = elem && elem.childNodes.length;
									while (j--) {
										if (jQuery.nodeName(
												(tbody = elem.childNodes[j]),
												"tbody")
												&& !tbody.childNodes.length) {
											elem.removeChild(tbody);
										}
									}
								}

								jQuery.merge(nodes, tmp.childNodes);

								// Fix #12392 for WebKit and IE > 9
								tmp.textContent = "";

								// Fix #12392 for oldIE
								while (tmp.firstChild) {
									tmp.removeChild(tmp.firstChild);
								}

								// Remember the top-level container for proper
								// cleanup
								tmp = safe.lastChild;
							}
						}
					}

					// Fix #11356: Clear elements from fragment
					if (tmp) {
						safe.removeChild(tmp);
					}

					// Reset defaultChecked for any radios and checkboxes
					// about to be appended to the DOM in IE 6/7 (#8060)
					if (!jQuery.support.appendChecked) {
						jQuery.grep(getAll(nodes, "input"), fixDefaultChecked);
					}

					i = 0;
					while ((elem = nodes[i++])) {

						// #4087 - If origin and destination elements are the
						// same, and this is
						// that element, do not do anything
						if (selection && jQuery.inArray(elem, selection) !== -1) {
							continue;
						}

						contains = jQuery.contains(elem.ownerDocument, elem);

						// Append to fragment
						tmp = getAll(safe.appendChild(elem), "script");

						// Preserve script evaluation history
						if (contains) {
							setGlobalEval(tmp);
						}

						// Capture executables
						if (scripts) {
							j = 0;
							while ((elem = tmp[j++])) {
								if (rscriptType.test(elem.type || "")) {
									scripts.push(elem);
								}
							}
						}
					}

					tmp = null;

					return safe;
				},

				cleanData : function(elems, /* internal */acceptData) {
					var elem, type, id, data, i = 0, internalKey = jQuery.expando, cache = jQuery.cache, deleteExpando = jQuery.support.deleteExpando, special = jQuery.event.special;

					for (; (elem = elems[i]) != null; i++) {

						if (acceptData || jQuery.acceptData(elem)) {

							id = elem[internalKey];
							data = id && cache[id];

							if (data) {
								if (data.events) {
									for (type in data.events) {
										if (special[type]) {
											jQuery.event.remove(elem, type);

											// This is a shortcut to avoid
											// jQuery.event.remove's overhead
										} else {
											jQuery.removeEvent(elem, type,
													data.handle);
										}
									}
								}

								// Remove cache only if it was not already
								// removed by jQuery.event.remove
								if (cache[id]) {

									delete cache[id];

									// IE does not allow us to delete expando
									// properties from nodes,
									// nor does it have a removeAttribute
									// function on Document nodes;
									// we must handle all of these cases
									if (deleteExpando) {
										delete elem[internalKey];

									} else if (typeof elem.removeAttribute !== core_strundefined) {
										elem.removeAttribute(internalKey);

									} else {
										elem[internalKey] = null;
									}

									core_deletedIds.push(id);
								}
							}
						}
					}
				}
			});
	var iframe, getStyles, curCSS, ralpha = /alpha\([^)]*\)/i, ropacity = /opacity\s*=\s*([^)]*)/, rposition = /^(top|right|bottom|left)$/,
	// swappable if display is none or starts with table except "table",
	// "table-cell", or "table-caption"
	// see here for display values:
	// https://developer.mozilla.org/en-US/docs/CSS/display
	rdisplayswap = /^(none|table(?!-c[ea]).+)/, rmargin = /^margin/, rnumsplit = new RegExp(
			"^(" + core_pnum + ")(.*)$", "i"), rnumnonpx = new RegExp("^("
			+ core_pnum + ")(?!px)[a-z%]+$", "i"), rrelNum = new RegExp(
			"^([+-])=(" + core_pnum + ")", "i"), elemdisplay = {
		BODY : "block"
	},

	cssShow = {
		position : "absolute",
		visibility : "hidden",
		display : "block"
	}, cssNormalTransform = {
		letterSpacing : 0,
		fontWeight : 400
	},

	cssExpand = [ "Top", "Right", "Bottom", "Left" ], cssPrefixes = [ "Webkit",
			"O", "Moz", "ms" ];

	// return a css property mapped to a potentially vendor prefixed property
	function vendorPropName(style, name) {

		// shortcut for names that are not vendor prefixed
		if (name in style) {
			return name;
		}

		// check for vendor prefixed names
		var capName = name.charAt(0).toUpperCase() + name.slice(1), origName = name, i = cssPrefixes.length;

		while (i--) {
			name = cssPrefixes[i] + capName;
			if (name in style) {
				return name;
			}
		}

		return origName;
	}

	function isHidden(elem, el) {
		// isHidden might be called from jQuery#filter function;
		// in that case, element will be second argument
		elem = el || elem;
		return jQuery.css(elem, "display") === "none"
				|| !jQuery.contains(elem.ownerDocument, elem);
	}

	function showHide(elements, show) {
		var display, elem, hidden, values = [], index = 0, length = elements.length;

		for (; index < length; index++) {
			elem = elements[index];
			if (!elem.style) {
				continue;
			}

			values[index] = jQuery._data(elem, "olddisplay");
			display = elem.style.display;
			if (show) {
				// Reset the inline display of this element to learn if it is
				// being hidden by cascaded rules or not
				if (!values[index] && display === "none") {
					elem.style.display = "";
				}

				// Set elements which have been overridden with display: none
				// in a stylesheet to whatever the default browser style is
				// for such an element
				if (elem.style.display === "" && isHidden(elem)) {
					values[index] = jQuery._data(elem, "olddisplay",
							css_defaultDisplay(elem.nodeName));
				}
			} else {

				if (!values[index]) {
					hidden = isHidden(elem);

					if (display && display !== "none" || !hidden) {
						jQuery._data(elem, "olddisplay", hidden ? display
								: jQuery.css(elem, "display"));
					}
				}
			}
		}

		// Set the display of most of the elements in a second loop
		// to avoid the constant reflow
		for (index = 0; index < length; index++) {
			elem = elements[index];
			if (!elem.style) {
				continue;
			}
			if (!show || elem.style.display === "none"
					|| elem.style.display === "") {
				elem.style.display = show ? values[index] || "" : "none";
			}
		}

		return elements;
	}

	jQuery.fn.extend({
		css : function(name, value) {
			return jQuery.access(this,
					function(elem, name, value) {
						var len, styles, map = {}, i = 0;

						if (jQuery.isArray(name)) {
							styles = getStyles(elem);
							len = name.length;

							for (; i < len; i++) {
								map[name[i]] = jQuery.css(elem, name[i], false,
										styles);
							}

							return map;
						}

						return value !== undefined ? jQuery.style(elem, name,
								value) : jQuery.css(elem, name);
					}, name, value, arguments.length > 1);
		},
		show : function() {
			return showHide(this, true);
		},
		hide : function() {
			return showHide(this);
		},
		toggle : function(state) {
			var bool = typeof state === "boolean";

			return this.each(function() {
				if (bool ? state : isHidden(this)) {
					jQuery(this).show();
				} else {
					jQuery(this).hide();
				}
			});
		}
	});

	jQuery
			.extend({
				// Add in style property hooks for overriding the default
				// behavior of getting and setting a style property
				cssHooks : {
					opacity : {
						get : function(elem, computed) {
							if (computed) {
								// We should always get a number back from
								// opacity
								var ret = curCSS(elem, "opacity");
								return ret === "" ? "1" : ret;
							}
						}
					}
				},

				// Exclude the following css properties to add px
				cssNumber : {
					"columnCount" : true,
					"fillOpacity" : true,
					"fontWeight" : true,
					"lineHeight" : true,
					"opacity" : true,
					"orphans" : true,
					"widows" : true,
					"zIndex" : true,
					"zoom" : true
				},

				// Add in properties whose names you wish to fix before
				// setting or getting the value
				cssProps : {
					// normalize float css property
					"float" : jQuery.support.cssFloat ? "cssFloat"
							: "styleFloat"
				},

				// Get and set the style property on a DOM Node
				style : function(elem, name, value, extra) {
					// Don't set styles on text and comment nodes
					if (!elem || elem.nodeType === 3 || elem.nodeType === 8
							|| !elem.style) {
						return;
					}

					// Make sure that we're working with the right name
					var ret, type, hooks, origName = jQuery.camelCase(name), style = elem.style;

					name = jQuery.cssProps[origName]
							|| (jQuery.cssProps[origName] = vendorPropName(
									style, origName));

					// gets hook for the prefixed version
					// followed by the unprefixed version
					hooks = jQuery.cssHooks[name] || jQuery.cssHooks[origName];

					// Check if we're setting a value
					if (value !== undefined) {
						type = typeof value;

						// convert relative number strings (+= or -=) to
						// relative numbers. #7345
						if (type === "string" && (ret = rrelNum.exec(value))) {
							value = (ret[1] + 1) * ret[2]
									+ parseFloat(jQuery.css(elem, name));
							// Fixes bug #9237
							type = "number";
						}

						// Make sure that NaN and null values aren't set. See:
						// #7116
						if (value == null || type === "number" && isNaN(value)) {
							return;
						}

						// If a number was passed in, add 'px' to the (except
						// for certain CSS properties)
						if (type === "number" && !jQuery.cssNumber[origName]) {
							value += "px";
						}

						// Fixes #8908, it can be done more correctly by
						// specifing setters in cssHooks,
						// but it would mean to define eight (for every
						// problematic property) identical functions
						if (!jQuery.support.clearCloneStyle && value === ""
								&& name.indexOf("background") === 0) {
							style[name] = "inherit";
						}

						// If a hook was provided, use that value, otherwise
						// just set the specified value
						if (!hooks
								|| !("set" in hooks)
								|| (value = hooks.set(elem, value, extra)) !== undefined) {

							// Wrapped to prevent IE from throwing errors when
							// 'invalid' values are provided
							// Fixes bug #5509
							try {
								style[name] = value;
							} catch (e) {
							}
						}

					} else {
						// If a hook was provided get the non-computed value
						// from there
						if (hooks
								&& "get" in hooks
								&& (ret = hooks.get(elem, false, extra)) !== undefined) {
							return ret;
						}

						// Otherwise just get the value from the style object
						return style[name];
					}
				},

				css : function(elem, name, extra, styles) {
					var num, val, hooks, origName = jQuery.camelCase(name);

					// Make sure that we're working with the right name
					name = jQuery.cssProps[origName]
							|| (jQuery.cssProps[origName] = vendorPropName(
									elem.style, origName));

					// gets hook for the prefixed version
					// followed by the unprefixed version
					hooks = jQuery.cssHooks[name] || jQuery.cssHooks[origName];

					// If a hook was provided get the computed value from there
					if (hooks && "get" in hooks) {
						val = hooks.get(elem, true, extra);
					}

					// Otherwise, if a way to get the computed value exists, use
					// that
					if (val === undefined) {
						val = curCSS(elem, name, styles);
					}

					// convert "normal" to computed value
					if (val === "normal" && name in cssNormalTransform) {
						val = cssNormalTransform[name];
					}

					// Return, converting to number if forced or a qualifier was
					// provided and val looks numeric
					if (extra === "" || extra) {
						num = parseFloat(val);
						return extra === true || jQuery.isNumeric(num) ? num || 0
								: val;
					}
					return val;
				},

				// A method for quickly swapping in/out CSS properties to get
				// correct calculations
				swap : function(elem, options, callback, args) {
					var ret, name, old = {};

					// Remember the old values, and insert the new ones
					for (name in options) {
						old[name] = elem.style[name];
						elem.style[name] = options[name];
					}

					ret = callback.apply(elem, args || []);

					// Revert the old values
					for (name in options) {
						elem.style[name] = old[name];
					}

					return ret;
				}
			});

	// NOTE: we've included the "window" in window.getComputedStyle
	// because jsdom on node.js will break without it.
	if (window.getComputedStyle) {
		getStyles = function(elem) {
			return window.getComputedStyle(elem, null);
		};

		curCSS = function(elem, name, _computed) {
			var width, minWidth, maxWidth, computed = _computed
					|| getStyles(elem),

			// getPropertyValue is only needed for .css('filter') in IE9, see
			// #12537
			ret = computed ? computed.getPropertyValue(name) || computed[name]
					: undefined, style = elem.style;

			if (computed) {

				if (ret === "" && !jQuery.contains(elem.ownerDocument, elem)) {
					ret = jQuery.style(elem, name);
				}

				// A tribute to the "awesome hack by Dean Edwards"
				// Chrome < 17 and Safari 5.0 uses "computed value" instead of
				// "used value" for margin-right
				// Safari 5.1.7 (at least) returns percentage for a larger set
				// of values, but width seems to be reliably pixels
				// this is against the CSSOM draft spec:
				// http://dev.w3.org/csswg/cssom/#resolved-values
				if (rnumnonpx.test(ret) && rmargin.test(name)) {

					// Remember the original values
					width = style.width;
					minWidth = style.minWidth;
					maxWidth = style.maxWidth;

					// Put in the new values to get a computed value out
					style.minWidth = style.maxWidth = style.width = ret;
					ret = computed.width;

					// Revert the changed values
					style.width = width;
					style.minWidth = minWidth;
					style.maxWidth = maxWidth;
				}
			}

			return ret;
		};
	} else if (document.documentElement.currentStyle) {
		getStyles = function(elem) {
			return elem.currentStyle;
		};

		curCSS = function(elem, name, _computed) {
			var left, rs, rsLeft, computed = _computed || getStyles(elem), ret = computed ? computed[name]
					: undefined, style = elem.style;

			// Avoid setting ret to empty string here
			// so we don't default to auto
			if (ret == null && style && style[name]) {
				ret = style[name];
			}

			// From the awesome hack by Dean Edwards
			// http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291

			// If we're not dealing with a regular pixel number
			// but a number that has a weird ending, we need to convert it to
			// pixels
			// but not position css attributes, as those are proportional to the
			// parent element instead
			// and we can't measure the parent instead because it might trigger
			// a "stacking dolls" problem
			if (rnumnonpx.test(ret) && !rposition.test(name)) {

				// Remember the original values
				left = style.left;
				rs = elem.runtimeStyle;
				rsLeft = rs && rs.left;

				// Put in the new values to get a computed value out
				if (rsLeft) {
					rs.left = elem.currentStyle.left;
				}
				style.left = name === "fontSize" ? "1em" : ret;
				ret = style.pixelLeft + "px";

				// Revert the changed values
				style.left = left;
				if (rsLeft) {
					rs.left = rsLeft;
				}
			}

			return ret === "" ? "auto" : ret;
		};
	}

	function setPositiveNumber(elem, value, subtract) {
		var matches = rnumsplit.exec(value);
		return matches ?
		// Guard against undefined "subtract", e.g., when used as in cssHooks
		Math.max(0, matches[1] - (subtract || 0)) + (matches[2] || "px")
				: value;
	}

	function augmentWidthOrHeight(elem, name, extra, isBorderBox, styles) {
		var i = extra === (isBorderBox ? "border" : "content") ?
		// If we already have the right measurement, avoid augmentation
		4 :
		// Otherwise initialize for horizontal or vertical properties
		name === "width" ? 1 : 0,

		val = 0;

		for (; i < 4; i += 2) {
			// both box models exclude margin, so add it if we want it
			if (extra === "margin") {
				val += jQuery.css(elem, extra + cssExpand[i], true, styles);
			}

			if (isBorderBox) {
				// border-box includes padding, so remove it if we want content
				if (extra === "content") {
					val -= jQuery.css(elem, "padding" + cssExpand[i], true,
							styles);
				}

				// at this point, extra isn't border nor margin, so remove
				// border
				if (extra !== "margin") {
					val -= jQuery.css(elem, "border" + cssExpand[i] + "Width",
							true, styles);
				}
			} else {
				// at this point, extra isn't content, so add padding
				val += jQuery.css(elem, "padding" + cssExpand[i], true, styles);

				// at this point, extra isn't content nor padding, so add border
				if (extra !== "padding") {
					val += jQuery.css(elem, "border" + cssExpand[i] + "Width",
							true, styles);
				}
			}
		}

		return val;
	}

	function getWidthOrHeight(elem, name, extra) {

		// Start with offset property, which is equivalent to the border-box
		// value
		var valueIsBorderBox = true, val = name === "width" ? elem.offsetWidth
				: elem.offsetHeight, styles = getStyles(elem), isBorderBox = jQuery.support.boxSizing
				&& jQuery.css(elem, "boxSizing", false, styles) === "border-box";

		// some non-html elements return undefined for offsetWidth, so check for
		// null/undefined
		// svg - https://bugzilla.mozilla.org/show_bug.cgi?id=649285
		// MathML - https://bugzilla.mozilla.org/show_bug.cgi?id=491668
		if (val <= 0 || val == null) {
			// Fall back to computed then uncomputed css if necessary
			val = curCSS(elem, name, styles);
			if (val < 0 || val == null) {
				val = elem.style[name];
			}

			// Computed unit is not pixels. Stop here and return.
			if (rnumnonpx.test(val)) {
				return val;
			}

			// we need the check for style in case a browser which returns
			// unreliable values
			// for getComputedStyle silently falls back to the reliable
			// elem.style
			valueIsBorderBox = isBorderBox
					&& (jQuery.support.boxSizingReliable || val === elem.style[name]);

			// Normalize "", auto, and prepare for extra
			val = parseFloat(val) || 0;
		}

		// use the active box-sizing model to add/subtract irrelevant styles
		return (val + augmentWidthOrHeight(elem, name, extra
				|| (isBorderBox ? "border" : "content"), valueIsBorderBox,
				styles))
				+ "px";
	}

	// Try to determine the default display value of an element
	function css_defaultDisplay(nodeName) {
		var doc = document, display = elemdisplay[nodeName];

		if (!display) {
			display = actualDisplay(nodeName, doc);

			// If the simple way fails, read from inside an iframe
			if (display === "none" || !display) {
				// Use the already-created iframe if possible
				iframe = (iframe || jQuery(
						"<iframe frameborder='0' width='0' height='0'/>").css(
						"cssText", "display:block !important"))
						.appendTo(doc.documentElement);

				// Always write a new HTML skeleton so Webkit and Firefox don't
				// choke on reuse
				doc = (iframe[0].contentWindow || iframe[0].contentDocument).document;
				doc.write("<!doctype html><html><body>");
				doc.close();

				display = actualDisplay(nodeName, doc);
				iframe.detach();
			}

			// Store the correct default display
			elemdisplay[nodeName] = display;
		}

		return display;
	}

	// Called ONLY from within css_defaultDisplay
	function actualDisplay(name, doc) {
		var elem = jQuery(doc.createElement(name)).appendTo(doc.body), display = jQuery
				.css(elem[0], "display");
		elem.remove();
		return display;
	}

	jQuery
			.each(
					[ "height", "width" ],
					function(i, name) {
						jQuery.cssHooks[name] = {
							get : function(elem, computed, extra) {
								if (computed) {
									// certain elements can have dimension info
									// if we invisibly show them
									// however, it must have a current display
									// style that would benefit from this
									return elem.offsetWidth === 0
											&& rdisplayswap.test(jQuery.css(
													elem, "display")) ? jQuery
											.swap(elem, cssShow, function() {
												return getWidthOrHeight(elem,
														name, extra);
											}) : getWidthOrHeight(elem, name,
											extra);
								}
							},

							set : function(elem, value, extra) {
								var styles = extra && getStyles(elem);
								return setPositiveNumber(
										elem,
										value,
										extra ? augmentWidthOrHeight(
												elem,
												name,
												extra,
												jQuery.support.boxSizing
														&& jQuery.css(elem,
																"boxSizing",
																false, styles) === "border-box",
												styles)
												: 0);
							}
						};
					});

	if (!jQuery.support.opacity) {
		jQuery.cssHooks.opacity = {
			get : function(elem, computed) {
				// IE uses filters for opacity
				return ropacity
						.test((computed && elem.currentStyle ? elem.currentStyle.filter
								: elem.style.filter)
								|| "") ? (0.01 * parseFloat(RegExp.$1)) + ""
						: computed ? "1" : "";
			},

			set : function(elem, value) {
				var style = elem.style, currentStyle = elem.currentStyle, opacity = jQuery
						.isNumeric(value) ? "alpha(opacity=" + value * 100
						+ ")" : "", filter = currentStyle
						&& currentStyle.filter || style.filter || "";

				// IE has trouble with opacity if it does not have layout
				// Force it by setting the zoom level
				style.zoom = 1;

				// if setting opacity to 1, and no other filters exist - attempt
				// to remove filter attribute #6652
				// if value === "", then remove inline opacity #12685
				if ((value >= 1 || value === "")
						&& jQuery.trim(filter.replace(ralpha, "")) === ""
						&& style.removeAttribute) {

					// Setting style.filter to null, "" & " " still leave
					// "filter:" in the cssText
					// if "filter:" is present at all, clearType is disabled, we
					// want to avoid this
					// style.removeAttribute is IE Only, but so apparently is
					// this code path...
					style.removeAttribute("filter");

					// if there is no filter style applied in a css rule or
					// unset inline opacity, we are done
					if (value === "" || currentStyle && !currentStyle.filter) {
						return;
					}
				}

				// otherwise, set new filter values
				style.filter = ralpha.test(filter) ? filter.replace(ralpha,
						opacity) : filter + " " + opacity;
			}
		};
	}

	// These hooks cannot be added until DOM ready because the support test
	// for it is not run until after DOM ready
	jQuery(function() {
		if (!jQuery.support.reliableMarginRight) {
			jQuery.cssHooks.marginRight = {
				get : function(elem, computed) {
					if (computed) {
						// WebKit Bug 13343 - getComputedStyle returns wrong
						// value for margin-right
						// Work around by temporarily setting element display to
						// inline-block
						return jQuery.swap(elem, {
							"display" : "inline-block"
						}, curCSS, [ elem, "marginRight" ]);
					}
				}
			};
		}

		// Webkit bug: https://bugs.webkit.org/show_bug.cgi?id=29084
		// getComputedStyle returns percent when specified for
		// top/left/bottom/right
		// rather than make the css module depend on the offset module, we just
		// check for it here
		if (!jQuery.support.pixelPosition && jQuery.fn.position) {
			jQuery.each([ "top", "left" ], function(i, prop) {
				jQuery.cssHooks[prop] = {
					get : function(elem, computed) {
						if (computed) {
							computed = curCSS(elem, prop);
							// if curCSS returns percentage, fallback to offset
							return rnumnonpx.test(computed) ? jQuery(elem)
									.position()[prop]
									+ "px" : computed;
						}
					}
				};
			});
		}

	});

	if (jQuery.expr && jQuery.expr.filters) {
		jQuery.expr.filters.hidden = function(elem) {
			// Support: Opera <= 12.12
			// Opera reports offsetWidths and offsetHeights less than zero on
			// some elements
			return elem.offsetWidth <= 0
					&& elem.offsetHeight <= 0
					|| (!jQuery.support.reliableHiddenOffsets && ((elem.style && elem.style.display) || jQuery
							.css(elem, "display")) === "none");
		};

		jQuery.expr.filters.visible = function(elem) {
			return !jQuery.expr.filters.hidden(elem);
		};
	}

	// These hooks are used by animate to expand properties
	jQuery.each({
		margin : "",
		padding : "",
		border : "Width"
	}, function(prefix, suffix) {
		jQuery.cssHooks[prefix + suffix] = {
			expand : function(value) {
				var i = 0, expanded = {},

				// assumes a single number if not a string
				parts = typeof value === "string" ? value.split(" ")
						: [ value ];

				for (; i < 4; i++) {
					expanded[prefix + cssExpand[i] + suffix] = parts[i]
							|| parts[i - 2] || parts[0];
				}

				return expanded;
			}
		};

		if (!rmargin.test(prefix)) {
			jQuery.cssHooks[prefix + suffix].set = setPositiveNumber;
		}
	});
	var r20 = /%20/g, rbracket = /\[\]$/, rCRLF = /\r?\n/g, rsubmitterTypes = /^(?:submit|button|image|reset|file)$/i, rsubmittable = /^(?:input|select|textarea|keygen)/i;

	jQuery.fn
			.extend({
				serialize : function() {
					return jQuery.param(this.serializeArray());
				},
				serializeArray : function() {
					return this
							.map(
									function() {
										// Can add propHook for "elements" to
										// filter or add form elements
										var elements = jQuery.prop(this,
												"elements");
										return elements ? jQuery
												.makeArray(elements) : this;
									})
							.filter(
									function() {
										var type = this.type;
										// Use .is(":disabled") so that
										// fieldset[disabled] works
										return this.name
												&& !jQuery(this)
														.is(":disabled")
												&& rsubmittable
														.test(this.nodeName)
												&& !rsubmitterTypes.test(type)
												&& (this.checked || !manipulation_rcheckableType
														.test(type));
									}).map(
									function(i, elem) {
										var val = jQuery(this).val();

										return val == null ? null : jQuery
												.isArray(val) ? jQuery.map(val,
												function(val) {
													return {
														name : elem.name,
														value : val.replace(
																rCRLF, "\r\n")
													};
												}) : {
											name : elem.name,
											value : val.replace(rCRLF, "\r\n")
										};
									}).get();
				}
			});

	// Serialize an array of form elements or a set of
	// key/values into a query string
	jQuery.param = function(a, traditional) {
		var prefix, s = [], add = function(key, value) {
			// If value is a function, invoke it and return its value
			value = jQuery.isFunction(value) ? value() : (value == null ? ""
					: value);
			s[s.length] = encodeURIComponent(key) + "="
					+ encodeURIComponent(value);
		};

		// Set traditional to true for jQuery <= 1.3.2 behavior.
		if (traditional === undefined) {
			traditional = jQuery.ajaxSettings
					&& jQuery.ajaxSettings.traditional;
		}

		// If an array was passed in, assume that it is an array of form
		// elements.
		if (jQuery.isArray(a) || (a.jquery && !jQuery.isPlainObject(a))) {
			// Serialize the form elements
			jQuery.each(a, function() {
				add(this.name, this.value);
			});

		} else {
			// If traditional, encode the "old" way (the way 1.3.2 or older
			// did it), otherwise encode params recursively.
			for (prefix in a) {
				buildParams(prefix, a[prefix], traditional, add);
			}
		}

		// Return the resulting serialization
		return s.join("&").replace(r20, "+");
	};

	function buildParams(prefix, obj, traditional, add) {
		var name;

		if (jQuery.isArray(obj)) {
			// Serialize array item.
			jQuery.each(obj, function(i, v) {
				if (traditional || rbracket.test(prefix)) {
					// Treat each array item as a scalar.
					add(prefix, v);

				} else {
					// Item is non-scalar (array or object), encode its numeric
					// index.
					buildParams(prefix + "[" + (typeof v === "object" ? i : "")
							+ "]", v, traditional, add);
				}
			});

		} else if (!traditional && jQuery.type(obj) === "object") {
			// Serialize object item.
			for (name in obj) {
				buildParams(prefix + "[" + name + "]", obj[name], traditional,
						add);
			}

		} else {
			// Serialize scalar item.
			add(prefix, obj);
		}
	}
	jQuery
			.each(
					("blur focus focusin focusout load resize scroll unload click dblclick "
							+ "mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave "
							+ "change select submit keydown keypress keyup error contextmenu")
							.split(" "), function(i, name) {

						// Handle event binding
						jQuery.fn[name] = function(data, fn) {
							return arguments.length > 0 ? this.on(name, null,
									data, fn) : this.trigger(name);
						};
					});

	jQuery.fn.hover = function(fnOver, fnOut) {
		return this.mouseenter(fnOver).mouseleave(fnOut || fnOver);
	};
	var
	// Document location
	ajaxLocParts, ajaxLocation, ajax_nonce = jQuery.now(),

	ajax_rquery = /\?/, rhash = /#.*$/, rts = /([?&])_=[^&]*/, rheaders = /^(.*?):[ \t]*([^\r\n]*)\r?$/mg, // IE
																											// leaves
																											// an
																											// \r
																											// character
																											// at
																											// EOL
	// #7653, #8125, #8152: local protocol detection
	rlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/, rnoContent = /^(?:GET|HEAD)$/, rprotocol = /^\/\//, rurl = /^([\w.+-]+:)(?:\/\/([^\/?#:]*)(?::(\d+)|)|)/,

	// Keep a copy of the old load method
	_load = jQuery.fn.load,

	/*
	 * Prefilters 1) They are useful to introduce custom dataTypes (see
	 * ajax/jsonp.js for an example) 2) These are called: - BEFORE asking for a
	 * transport - AFTER param serialization (s.data is a string if
	 * s.processData is true) 3) key is the dataType 4) the catchall symbol "*"
	 * can be used 5) execution will start with transport dataType and THEN
	 * continue down to "*" if needed
	 */
	prefilters = {},

	/*
	 * Transports bindings 1) key is the dataType 2) the catchall symbol "*" can
	 * be used 3) selection will start with transport dataType and THEN go to
	 * "*" if needed
	 */
	transports = {},

	// Avoid comment-prolog char sequence (#10098); must appease lint and evade
	// compression
	allTypes = "*/".concat("*");

	// #8138, IE may throw an exception when accessing
	// a field from window.location if document.domain has been set
	try {
		ajaxLocation = location.href;
	} catch (e) {
		// Use the href attribute of an A element
		// since IE will modify it given document.location
		ajaxLocation = document.createElement("a");
		ajaxLocation.href = "";
		ajaxLocation = ajaxLocation.href;
	}

	// Segment location into parts
	ajaxLocParts = rurl.exec(ajaxLocation.toLowerCase()) || [];

	// Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport
	function addToPrefiltersOrTransports(structure) {

		// dataTypeExpression is optional and defaults to "*"
		return function(dataTypeExpression, func) {

			if (typeof dataTypeExpression !== "string") {
				func = dataTypeExpression;
				dataTypeExpression = "*";
			}

			var dataType, i = 0, dataTypes = dataTypeExpression.toLowerCase()
					.match(core_rnotwhite)
					|| [];

			if (jQuery.isFunction(func)) {
				// For each dataType in the dataTypeExpression
				while ((dataType = dataTypes[i++])) {
					// Prepend if requested
					if (dataType[0] === "+") {
						dataType = dataType.slice(1) || "*";
						(structure[dataType] = structure[dataType] || [])
								.unshift(func);

						// Otherwise append
					} else {
						(structure[dataType] = structure[dataType] || [])
								.push(func);
					}
				}
			}
		};
	}

	// Base inspection function for prefilters and transports
	function inspectPrefiltersOrTransports(structure, options, originalOptions,
			jqXHR) {

		var inspected = {}, seekingTransport = (structure === transports);

		function inspect(dataType) {
			var selected;
			inspected[dataType] = true;
			jQuery.each(structure[dataType] || [],
					function(_, prefilterOrFactory) {
						var dataTypeOrTransport = prefilterOrFactory(options,
								originalOptions, jqXHR);
						if (typeof dataTypeOrTransport === "string"
								&& !seekingTransport
								&& !inspected[dataTypeOrTransport]) {
							options.dataTypes.unshift(dataTypeOrTransport);
							inspect(dataTypeOrTransport);
							return false;
						} else if (seekingTransport) {
							return !(selected = dataTypeOrTransport);
						}
					});
			return selected;
		}

		return inspect(options.dataTypes[0]) || !inspected["*"] && inspect("*");
	}

	// A special extend for ajax options
	// that takes "flat" options (not to be deep extended)
	// Fixes #9887
	function ajaxExtend(target, src) {
		var deep, key, flatOptions = jQuery.ajaxSettings.flatOptions || {};

		for (key in src) {
			if (src[key] !== undefined) {
				(flatOptions[key] ? target : (deep || (deep = {})))[key] = src[key];
			}
		}
		if (deep) {
			jQuery.extend(true, target, deep);
		}

		return target;
	}

	jQuery.fn.load = function(url, params, callback) {
		if (typeof url !== "string" && _load) {
			return _load.apply(this, arguments);
		}

		var selector, response, type, self = this, off = url.indexOf(" ");

		if (off >= 0) {
			selector = url.slice(off, url.length);
			url = url.slice(0, off);
		}

		// If it's a function
		if (jQuery.isFunction(params)) {

			// We assume that it's the callback
			callback = params;
			params = undefined;

			// Otherwise, build a param string
		} else if (params && typeof params === "object") {
			type = "POST";
		}

		// If we have elements to modify, make the request
		if (self.length > 0) {
			jQuery.ajax({
				url : url,

				// if "type" variable is undefined, then "GET" method will be
				// used
				type : type,
				dataType : "html",
				data : params
			}).done(
					function(responseText) {

						// Save response for use in complete callback
						response = arguments;

						self.html(selector ?

						// If a selector was specified, locate the right
						// elements in a dummy div
						// Exclude scripts to avoid IE 'Permission Denied'
						// errors
						jQuery("<div>").append(jQuery.parseHTML(responseText))
								.find(selector) :

						// Otherwise use the full result
						responseText);

					}).complete(
					callback
							&& function(jqXHR, status) {
								self.each(callback,
										response
												|| [ jqXHR.responseText,
														status, jqXHR ]);
							});
		}

		return this;
	};

	// Attach a bunch of functions for handling common AJAX events
	jQuery.each([ "ajaxStart", "ajaxStop", "ajaxComplete", "ajaxError",
			"ajaxSuccess", "ajaxSend" ], function(i, type) {
		jQuery.fn[type] = function(fn) {
			return this.on(type, fn);
		};
	});

	jQuery.each([ "get", "post" ], function(i, method) {
		jQuery[method] = function(url, data, callback, type) {
			// shift arguments if data argument was omitted
			if (jQuery.isFunction(data)) {
				type = type || callback;
				callback = data;
				data = undefined;
			}

			return jQuery.ajax({
				url : url,
				type : method,
				dataType : type,
				data : data,
				success : callback
			});
		};
	});

	jQuery
			.extend({

				// Counter for holding the number of active queries
				active : 0,

				// Last-Modified header cache for next request
				lastModified : {},
				etag : {},

				ajaxSettings : {
					url : ajaxLocation,
					type : "GET",
					isLocal : rlocalProtocol.test(ajaxLocParts[1]),
					global : true,
					processData : true,
					async : true,
					contentType : "application/x-www-form-urlencoded; charset=UTF-8",
					/*
					 * timeout: 0, data: null, dataType: null, username: null,
					 * password: null, cache: null, throws: false, traditional:
					 * false, headers: {},
					 */

					accepts : {
						"*" : allTypes,
						text : "text/plain",
						html : "text/html",
						xml : "application/xml, text/xml",
						json : "application/json, text/javascript"
					},

					contents : {
						xml : /xml/,
						html : /html/,
						json : /json/
					},

					responseFields : {
						xml : "responseXML",
						text : "responseText"
					},

					// Data converters
					// Keys separate source (or catchall "*") and destination
					// types with a single space
					converters : {

						// Convert anything to text
						"* text" : window.String,

						// Text to html (true = no transformation)
						"text html" : true,

						// Evaluate text as a json expression
						"text json" : jQuery.parseJSON,

						// Parse text as xml
						"text xml" : jQuery.parseXML
					},

					// For options that shouldn't be deep extended:
					// you can add your own custom options here if
					// and when you create one that shouldn't be
					// deep extended (see ajaxExtend)
					flatOptions : {
						url : true,
						context : true
					}
				},

				// Creates a full fledged settings object into target
				// with both ajaxSettings and settings fields.
				// If target is omitted, writes into ajaxSettings.
				ajaxSetup : function(target, settings) {
					return settings ?

					// Building a settings object
					ajaxExtend(ajaxExtend(target, jQuery.ajaxSettings),
							settings) :

					// Extending ajaxSettings
					ajaxExtend(jQuery.ajaxSettings, target);
				},

				ajaxPrefilter : addToPrefiltersOrTransports(prefilters),
				ajaxTransport : addToPrefiltersOrTransports(transports),

				// Main method
				ajax : function(url, options) {

					// If url is an object, simulate pre-1.5 signature
					if (typeof url === "object") {
						options = url;
						url = undefined;
					}

					// Force options to be an object
					options = options || {};

					var // Cross-domain detection vars
					parts,
					// Loop variable
					i,
					// URL without anti-cache param
					cacheURL,
					// Response headers as string
					responseHeadersString,
					// timeout handle
					timeoutTimer,

					// To know if global events are to be dispatched
					fireGlobals,

					transport,
					// Response headers
					responseHeaders,
					// Create the final options object
					s = jQuery.ajaxSetup({}, options),
					// Callbacks context
					callbackContext = s.context || s,
					// Context for global events is callbackContext if it is a
					// DOM node or jQuery collection
					globalEventContext = s.context
							&& (callbackContext.nodeType || callbackContext.jquery) ? jQuery(callbackContext)
							: jQuery.event,
					// Deferreds
					deferred = jQuery.Deferred(), completeDeferred = jQuery
							.Callbacks("once memory"),
					// Status-dependent callbacks
					statusCode = s.statusCode || {},
					// Headers (they are sent all at once)
					requestHeaders = {}, requestHeadersNames = {},
					// The jqXHR state
					state = 0,
					// Default abort message
					strAbort = "canceled",
					// Fake xhr
					jqXHR = {
						readyState : 0,

						// Builds headers hashtable if needed
						getResponseHeader : function(key) {
							var match;
							if (state === 2) {
								if (!responseHeaders) {
									responseHeaders = {};
									while ((match = rheaders
											.exec(responseHeadersString))) {
										responseHeaders[match[1].toLowerCase()] = match[2];
									}
								}
								match = responseHeaders[key.toLowerCase()];
							}
							return match == null ? null : match;
						},

						// Raw string
						getAllResponseHeaders : function() {
							return state === 2 ? responseHeadersString : null;
						},

						// Caches the header
						setRequestHeader : function(name, value) {
							var lname = name.toLowerCase();
							if (!state) {
								name = requestHeadersNames[lname] = requestHeadersNames[lname]
										|| name;
								requestHeaders[name] = value;
							}
							return this;
						},

						// Overrides response content-type header
						overrideMimeType : function(type) {
							if (!state) {
								s.mimeType = type;
							}
							return this;
						},

						// Status-dependent callbacks
						statusCode : function(map) {
							var code;
							if (map) {
								if (state < 2) {
									for (code in map) {
										// Lazy-add the new callback in a way
										// that preserves old ones
										statusCode[code] = [ statusCode[code],
												map[code] ];
									}
								} else {
									// Execute the appropriate callbacks
									jqXHR.always(map[jqXHR.status]);
								}
							}
							return this;
						},

						// Cancel the request
						abort : function(statusText) {
							var finalText = statusText || strAbort;
							if (transport) {
								transport.abort(finalText);
							}
							done(0, finalText);
							return this;
						}
					};

					// Attach deferreds
					deferred.promise(jqXHR).complete = completeDeferred.add;
					jqXHR.success = jqXHR.done;
					jqXHR.error = jqXHR.fail;

					// Remove hash character (#7531: and string promotion)
					// Add protocol if not provided (#5866: IE7 issue with
					// protocol-less urls)
					// Handle falsy url in the settings object (#10093:
					// consistency with old signature)
					// We also use the url parameter if available
					s.url = ((url || s.url || ajaxLocation) + "").replace(
							rhash, "").replace(rprotocol,
							ajaxLocParts[1] + "//");

					// Alias method option to type as per ticket #12004
					s.type = options.method || options.type || s.method
							|| s.type;

					// Extract dataTypes list
					s.dataTypes = jQuery.trim(s.dataType || "*").toLowerCase()
							.match(core_rnotwhite)
							|| [ "" ];

					// A cross-domain request is in order when we have a
					// protocol:host:port mismatch
					if (s.crossDomain == null) {
						parts = rurl.exec(s.url.toLowerCase());
						s.crossDomain = !!(parts && (parts[1] !== ajaxLocParts[1]
								|| parts[2] !== ajaxLocParts[2] || (parts[3] || (parts[1] === "http:" ? 80
								: 443)) != (ajaxLocParts[3] || (ajaxLocParts[1] === "http:" ? 80
								: 443))));
					}

					// Convert data if not already a string
					if (s.data && s.processData && typeof s.data !== "string") {
						s.data = jQuery.param(s.data, s.traditional);
					}

					// Apply prefilters
					inspectPrefiltersOrTransports(prefilters, s, options, jqXHR);

					// If request was aborted inside a prefilter, stop there
					if (state === 2) {
						return jqXHR;
					}

					// We can fire global events as of now if asked to
					fireGlobals = s.global;

					// Watch for a new set of requests
					if (fireGlobals && jQuery.active++ === 0) {
						jQuery.event.trigger("ajaxStart");
					}

					// Uppercase the type
					s.type = s.type.toUpperCase();

					// Determine if request has content
					s.hasContent = !rnoContent.test(s.type);

					// Save the URL in case we're toying with the
					// If-Modified-Since
					// and/or If-None-Match header later on
					cacheURL = s.url;

					// More options handling for requests with no content
					if (!s.hasContent) {

						// If data is available, append data to url
						if (s.data) {
							cacheURL = (s.url += (ajax_rquery.test(cacheURL) ? "&"
									: "?")
									+ s.data);
							// #9682: remove data so that it's not used in an
							// eventual retry
							delete s.data;
						}

						// Add anti-cache in url if needed
						if (s.cache === false) {
							s.url = rts.test(cacheURL) ?

							// If there is already a '_' parameter, set its
							// value
							cacheURL.replace(rts, "$1_=" + ajax_nonce++) :

							// Otherwise add one to the end
							cacheURL + (ajax_rquery.test(cacheURL) ? "&" : "?")
									+ "_=" + ajax_nonce++;
						}
					}

					// Set the If-Modified-Since and/or If-None-Match header, if
					// in ifModified mode.
					if (s.ifModified) {
						if (jQuery.lastModified[cacheURL]) {
							jqXHR.setRequestHeader("If-Modified-Since",
									jQuery.lastModified[cacheURL]);
						}
						if (jQuery.etag[cacheURL]) {
							jqXHR.setRequestHeader("If-None-Match",
									jQuery.etag[cacheURL]);
						}
					}

					// Set the correct header, if data is being sent
					if (s.data && s.hasContent && s.contentType !== false
							|| options.contentType) {
						jqXHR.setRequestHeader("Content-Type", s.contentType);
					}

					// Set the Accepts header for the server, depending on the
					// dataType
					jqXHR
							.setRequestHeader(
									"Accept",
									s.dataTypes[0] && s.accepts[s.dataTypes[0]] ? s.accepts[s.dataTypes[0]]
											+ (s.dataTypes[0] !== "*" ? ", "
													+ allTypes + "; q=0.01"
													: "")
											: s.accepts["*"]);

					// Check for headers option
					for (i in s.headers) {
						jqXHR.setRequestHeader(i, s.headers[i]);
					}

					// Allow custom headers/mimetypes and early abort
					if (s.beforeSend
							&& (s.beforeSend.call(callbackContext, jqXHR, s) === false || state === 2)) {
						// Abort if not done already and return
						return jqXHR.abort();
					}

					// aborting is no longer a cancellation
					strAbort = "abort";

					// Install callbacks on deferreds
					for (i in {
						success : 1,
						error : 1,
						complete : 1
					}) {
						jqXHR[i](s[i]);
					}

					// Get transport
					transport = inspectPrefiltersOrTransports(transports, s,
							options, jqXHR);

					// If no transport, we auto-abort
					if (!transport) {
						done(-1, "No Transport");
					} else {
						jqXHR.readyState = 1;

						// Send global event
						if (fireGlobals) {
							globalEventContext
									.trigger("ajaxSend", [ jqXHR, s ]);
						}
						// Timeout
						if (s.async && s.timeout > 0) {
							timeoutTimer = setTimeout(function() {
								jqXHR.abort("timeout");
							}, s.timeout);
						}

						try {
							state = 1;
							transport.send(requestHeaders, done);
						} catch (e) {
							// Propagate exception as error if not done
							if (state < 2) {
								done(-1, e);
								// Simply rethrow otherwise
							} else {
								throw e;
							}
						}
					}

					// Callback for when everything is done
					function done(status, nativeStatusText, responses, headers) {
						var isSuccess, success, error, response, modified, statusText = nativeStatusText;

						// Called once
						if (state === 2) {
							return;
						}

						// State is "done" now
						state = 2;

						// Clear timeout if it exists
						if (timeoutTimer) {
							clearTimeout(timeoutTimer);
						}

						// Dereference transport for early garbage collection
						// (no matter how long the jqXHR object will be used)
						transport = undefined;

						// Cache response headers
						responseHeadersString = headers || "";

						// Set readyState
						jqXHR.readyState = status > 0 ? 4 : 0;

						// Get response data
						if (responses) {
							response = ajaxHandleResponses(s, jqXHR, responses);
						}

						// If successful, handle type chaining
						if (status >= 200 && status < 300 || status === 304) {

							// Set the If-Modified-Since and/or If-None-Match
							// header, if in ifModified mode.
							if (s.ifModified) {
								modified = jqXHR
										.getResponseHeader("Last-Modified");
								if (modified) {
									jQuery.lastModified[cacheURL] = modified;
								}
								modified = jqXHR.getResponseHeader("etag");
								if (modified) {
									jQuery.etag[cacheURL] = modified;
								}
							}

							// if no content
							if (status === 204) {
								isSuccess = true;
								statusText = "nocontent";

								// if not modified
							} else if (status === 304) {
								isSuccess = true;
								statusText = "notmodified";

								// If we have data, let's convert it
							} else {
								isSuccess = ajaxConvert(s, response);
								statusText = isSuccess.state;
								success = isSuccess.data;
								error = isSuccess.error;
								isSuccess = !error;
							}
						} else {
							// We extract error from statusText
							// then normalize statusText and status for
							// non-aborts
							error = statusText;
							if (status || !statusText) {
								statusText = "error";
								if (status < 0) {
									status = 0;
								}
							}
						}

						// Set data for the fake xhr object
						jqXHR.status = status;
						jqXHR.statusText = (nativeStatusText || statusText)
								+ "";

						// Success/Error
						if (isSuccess) {
							deferred.resolveWith(callbackContext, [ success,
									statusText, jqXHR ]);
						} else {
							deferred.rejectWith(callbackContext, [ jqXHR,
									statusText, error ]);
						}

						// Status-dependent callbacks
						jqXHR.statusCode(statusCode);
						statusCode = undefined;

						if (fireGlobals) {
							globalEventContext.trigger(
									isSuccess ? "ajaxSuccess" : "ajaxError", [
											jqXHR, s,
											isSuccess ? success : error ]);
						}

						// Complete
						completeDeferred.fireWith(callbackContext, [ jqXHR,
								statusText ]);

						if (fireGlobals) {
							globalEventContext.trigger("ajaxComplete", [ jqXHR,
									s ]);
							// Handle the global AJAX counter
							if (!(--jQuery.active)) {
								jQuery.event.trigger("ajaxStop");
							}
						}
					}

					return jqXHR;
				},

				getScript : function(url, callback) {
					return jQuery.get(url, undefined, callback, "script");
				},

				getJSON : function(url, data, callback) {
					return jQuery.get(url, data, callback, "json");
				}
			});

	/*
	 * Handles responses to an ajax request: - sets all responseXXX fields
	 * accordingly - finds the right dataType (mediates between content-type and
	 * expected dataType) - returns the corresponding response
	 */
	function ajaxHandleResponses(s, jqXHR, responses) {
		var firstDataType, ct, finalDataType, type, contents = s.contents, dataTypes = s.dataTypes, responseFields = s.responseFields;

		// Fill responseXXX fields
		for (type in responseFields) {
			if (type in responses) {
				jqXHR[responseFields[type]] = responses[type];
			}
		}

		// Remove auto dataType and get content-type in the process
		while (dataTypes[0] === "*") {
			dataTypes.shift();
			if (ct === undefined) {
				ct = s.mimeType || jqXHR.getResponseHeader("Content-Type");
			}
		}

		// Check if we're dealing with a known content-type
		if (ct) {
			for (type in contents) {
				if (contents[type] && contents[type].test(ct)) {
					dataTypes.unshift(type);
					break;
				}
			}
		}

		// Check to see if we have a response for the expected dataType
		if (dataTypes[0] in responses) {
			finalDataType = dataTypes[0];
		} else {
			// Try convertible dataTypes
			for (type in responses) {
				if (!dataTypes[0] || s.converters[type + " " + dataTypes[0]]) {
					finalDataType = type;
					break;
				}
				if (!firstDataType) {
					firstDataType = type;
				}
			}
			// Or just use first one
			finalDataType = finalDataType || firstDataType;
		}

		// If we found a dataType
		// We add the dataType to the list if needed
		// and return the corresponding response
		if (finalDataType) {
			if (finalDataType !== dataTypes[0]) {
				dataTypes.unshift(finalDataType);
			}
			return responses[finalDataType];
		}
	}

	// Chain conversions given the request and the original response
	function ajaxConvert(s, response) {
		var conv2, current, conv, tmp, converters = {}, i = 0,
		// Work with a copy of dataTypes in case we need to modify it for
		// conversion
		dataTypes = s.dataTypes.slice(), prev = dataTypes[0];

		// Apply the dataFilter if provided
		if (s.dataFilter) {
			response = s.dataFilter(response, s.dataType);
		}

		// Create converters map with lowercased keys
		if (dataTypes[1]) {
			for (conv in s.converters) {
				converters[conv.toLowerCase()] = s.converters[conv];
			}
		}

		// Convert to each sequential dataType, tolerating list modification
		for (; (current = dataTypes[++i]);) {

			// There's only work to do if current dataType is non-auto
			if (current !== "*") {

				// Convert response if prev dataType is non-auto and differs
				// from current
				if (prev !== "*" && prev !== current) {

					// Seek a direct converter
					conv = converters[prev + " " + current]
							|| converters["* " + current];

					// If none found, seek a pair
					if (!conv) {
						for (conv2 in converters) {

							// If conv2 outputs current
							tmp = conv2.split(" ");
							if (tmp[1] === current) {

								// If prev can be converted to accepted input
								conv = converters[prev + " " + tmp[0]]
										|| converters["* " + tmp[0]];
								if (conv) {
									// Condense equivalence converters
									if (conv === true) {
										conv = converters[conv2];

										// Otherwise, insert the intermediate
										// dataType
									} else if (converters[conv2] !== true) {
										current = tmp[0];
										dataTypes.splice(i--, 0, current);
									}

									break;
								}
							}
						}
					}

					// Apply converter (if not an equivalence)
					if (conv !== true) {

						// Unless errors are allowed to bubble, catch and return
						// them
						if (conv && s["throws"]) {
							response = conv(response);
						} else {
							try {
								response = conv(response);
							} catch (e) {
								return {
									state : "parsererror",
									error : conv ? e : "No conversion from "
											+ prev + " to " + current
								};
							}
						}
					}
				}

				// Update prev for next iteration
				prev = current;
			}
		}

		return {
			state : "success",
			data : response
		};
	}
	// Install script dataType
	jQuery
			.ajaxSetup({
				accepts : {
					script : "text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"
				},
				contents : {
					script : /(?:java|ecma)script/
				},
				converters : {
					"text script" : function(text) {
						jQuery.globalEval(text);
						return text;
					}
				}
			});

	// Handle cache's special case and global
	jQuery.ajaxPrefilter("script", function(s) {
		if (s.cache === undefined) {
			s.cache = false;
		}
		if (s.crossDomain) {
			s.type = "GET";
			s.global = false;
		}
	});

	// Bind script tag hack transport
	jQuery.ajaxTransport("script", function(s) {

		// This transport only deals with cross domain requests
		if (s.crossDomain) {

			var script, head = document.head || jQuery("head")[0]
					|| document.documentElement;

			return {

				send : function(_, callback) {

					script = document.createElement("script");

					script.async = true;

					if (s.scriptCharset) {
						script.charset = s.scriptCharset;
					}

					script.src = s.url;

					// Attach handlers for all browsers
					script.onload = script.onreadystatechange = function(_,
							isAbort) {

						if (isAbort || !script.readyState
								|| /loaded|complete/.test(script.readyState)) {

							// Handle memory leak in IE
							script.onload = script.onreadystatechange = null;

							// Remove the script
							if (script.parentNode) {
								script.parentNode.removeChild(script);
							}

							// Dereference the script
							script = null;

							// Callback if not abort
							if (!isAbort) {
								callback(200, "success");
							}
						}
					};

					// Circumvent IE6 bugs with base elements (#2709 and #4378)
					// by prepending
					// Use native DOM manipulation to avoid our domManip AJAX
					// trickery
					head.insertBefore(script, head.firstChild);
				},

				abort : function() {
					if (script) {
						script.onload(undefined, true);
					}
				}
			};
		}
	});
	var oldCallbacks = [], rjsonp = /(=)\?(?=&|$)|\?\?/;

	// Default jsonp settings
	jQuery.ajaxSetup({
		jsonp : "callback",
		jsonpCallback : function() {
			var callback = oldCallbacks.pop()
					|| (jQuery.expando + "_" + (ajax_nonce++));
			this[callback] = true;
			return callback;
		}
	});

	// Detect, normalize options and install callbacks for jsonp requests
	jQuery
			.ajaxPrefilter(
					"json jsonp",
					function(s, originalSettings, jqXHR) {

						var callbackName, overwritten, responseContainer, jsonProp = s.jsonp !== false
								&& (rjsonp.test(s.url) ? "url"
										: typeof s.data === "string"
												&& !(s.contentType || "")
														.indexOf("application/x-www-form-urlencoded")
												&& rjsonp.test(s.data)
												&& "data");

						// Handle iff the expected data type is "jsonp" or we
						// have a parameter to set
						if (jsonProp || s.dataTypes[0] === "jsonp") {

							// Get callback name, remembering preexisting value
							// associated with it
							callbackName = s.jsonpCallback = jQuery
									.isFunction(s.jsonpCallback) ? s
									.jsonpCallback() : s.jsonpCallback;

							// Insert callback into url or form data
							if (jsonProp) {
								s[jsonProp] = s[jsonProp].replace(rjsonp, "$1"
										+ callbackName);
							} else if (s.jsonp !== false) {
								s.url += (ajax_rquery.test(s.url) ? "&" : "?")
										+ s.jsonp + "=" + callbackName;
							}

							// Use data converter to retrieve json after script
							// execution
							s.converters["script json"] = function() {
								if (!responseContainer) {
									jQuery.error(callbackName
											+ " was not called");
								}
								return responseContainer[0];
							};

							// force json dataType
							s.dataTypes[0] = "json";

							// Install callback
							overwritten = window[callbackName];
							window[callbackName] = function() {
								responseContainer = arguments;
							};

							// Clean-up function (fires after converters)
							jqXHR
									.always(function() {
										// Restore preexisting value
										window[callbackName] = overwritten;

										// Save back as free
										if (s[callbackName]) {
											// make sure that re-using the
											// options doesn't screw things
											// around
											s.jsonpCallback = originalSettings.jsonpCallback;

											// save the callback name for future
											// use
											oldCallbacks.push(callbackName);
										}

										// Call if it was a function and we have
										// a response
										if (responseContainer
												&& jQuery
														.isFunction(overwritten)) {
											overwritten(responseContainer[0]);
										}

										responseContainer = overwritten = undefined;
									});

							// Delegate to script
							return "script";
						}
					});
	var xhrCallbacks, xhrSupported, xhrId = 0,
	// #5280: Internet Explorer will keep connections alive if we don't abort on
	// unload
	xhrOnUnloadAbort = window.ActiveXObject && function() {
		// Abort all pending requests
		var key;
		for (key in xhrCallbacks) {
			xhrCallbacks[key](undefined, true);
		}
	};

	// Functions to create xhrs
	function createStandardXHR() {
		try {
			return new window.XMLHttpRequest();
		} catch (e) {
		}
	}

	function createActiveXHR() {
		try {
			return new window.ActiveXObject("Microsoft.XMLHTTP");
		} catch (e) {
		}
	}

	// Create the request object
	// (This is still attached to ajaxSettings for backward compatibility)
	jQuery.ajaxSettings.xhr = window.ActiveXObject ?
	/*
	 * Microsoft failed to properly implement the XMLHttpRequest in IE7 (can't
	 * request local files), so we use the ActiveXObject when it is available
	 * Additionally XMLHttpRequest can be disabled in IE7/IE8 so we need a
	 * fallback.
	 */
	function() {
		return !this.isLocal && createStandardXHR() || createActiveXHR();
	} :
	// For all other browsers, use the standard XMLHttpRequest object
	createStandardXHR;

	// Determine support properties
	xhrSupported = jQuery.ajaxSettings.xhr();
	jQuery.support.cors = !!xhrSupported && ("withCredentials" in xhrSupported);
	xhrSupported = jQuery.support.ajax = !!xhrSupported;

	// Create transport if the browser can provide an xhr
	if (xhrSupported) {

		jQuery
				.ajaxTransport(function(s) {
					// Cross domain only allowed if supported through
					// XMLHttpRequest
					if (!s.crossDomain || jQuery.support.cors) {

						var callback;

						return {
							send : function(headers, complete) {

								// Get a new xhr
								var handle, i, xhr = s.xhr();

								// Open the socket
								// Passing null username, generates a login
								// popup on Opera (#2865)
								if (s.username) {
									xhr.open(s.type, s.url, s.async,
											s.username, s.password);
								} else {
									xhr.open(s.type, s.url, s.async);
								}

								// Apply custom fields if provided
								if (s.xhrFields) {
									for (i in s.xhrFields) {
										xhr[i] = s.xhrFields[i];
									}
								}

								// Override mime type if needed
								if (s.mimeType && xhr.overrideMimeType) {
									xhr.overrideMimeType(s.mimeType);
								}

								// X-Requested-With header
								// For cross-domain requests, seeing as
								// conditions for a preflight are
								// akin to a jigsaw puzzle, we simply never set
								// it to be sure.
								// (it can always be set on a per-request basis
								// or even using ajaxSetup)
								// For same-domain requests, won't change header
								// if already provided.
								if (!s.crossDomain
										&& !headers["X-Requested-With"]) {
									headers["X-Requested-With"] = "XMLHttpRequest";
								}

								// Need an extra try/catch for cross domain
								// requests in Firefox 3
								try {
									for (i in headers) {
										xhr.setRequestHeader(i, headers[i]);
									}
								} catch (err) {
								}

								// Do send the request
								// This may raise an exception which is actually
								// handled in jQuery.ajax (so no try/catch here)
								xhr.send((s.hasContent && s.data) || null);

								// Listener
								callback = function(_, isAbort) {
									var status, responseHeaders, statusText, responses;

									// Firefox throws exceptions when accessing
									// properties
									// of an xhr when a network error occurred
									// http://helpful.knobs-dials.com/index.php/Component_returned_failure_code:_0x80040111_(NS_ERROR_NOT_AVAILABLE)
									try {

										// Was never called and is aborted or
										// complete
										if (callback
												&& (isAbort || xhr.readyState === 4)) {

											// Only called once
											callback = undefined;

											// Do not keep as active anymore
											if (handle) {
												xhr.onreadystatechange = jQuery.noop;
												if (xhrOnUnloadAbort) {
													delete xhrCallbacks[handle];
												}
											}

											// If it's an abort
											if (isAbort) {
												// Abort it manually if needed
												if (xhr.readyState !== 4) {
													xhr.abort();
												}
											} else {
												responses = {};
												status = xhr.status;
												responseHeaders = xhr
														.getAllResponseHeaders();

												// When requesting binary data,
												// IE6-9 will throw an exception
												// on any attempt to access
												// responseText (#11426)
												if (typeof xhr.responseText === "string") {
													responses.text = xhr.responseText;
												}

												// Firefox throws an exception
												// when accessing
												// statusText for faulty
												// cross-domain requests
												try {
													statusText = xhr.statusText;
												} catch (e) {
													// We normalize with Webkit
													// giving an empty
													// statusText
													statusText = "";
												}

												// Filter status for non
												// standard behaviors

												// If the request is local and
												// we have data: assume a
												// success
												// (success with no data won't
												// get notified, that's the best
												// we
												// can do given current
												// implementations)
												if (!status && s.isLocal
														&& !s.crossDomain) {
													status = responses.text ? 200
															: 404;
													// IE - #1450: sometimes
													// returns 1223 when it
													// should be 204
												} else if (status === 1223) {
													status = 204;
												}
											}
										}
									} catch (firefoxAccessException) {
										if (!isAbort) {
											complete(-1, firefoxAccessException);
										}
									}

									// Call complete if needed
									if (responses) {
										complete(status, statusText, responses,
												responseHeaders);
									}
								};

								if (!s.async) {
									// if we're in sync mode we fire the
									// callback
									callback();
								} else if (xhr.readyState === 4) {
									// (IE6 & IE7) if it's in cache and has been
									// retrieved directly we need to fire the
									// callback
									setTimeout(callback);
								} else {
									handle = ++xhrId;
									if (xhrOnUnloadAbort) {
										// Create the active xhrs callbacks list
										// if needed
										// and attach the unload handler
										if (!xhrCallbacks) {
											xhrCallbacks = {};
											jQuery(window).unload(
													xhrOnUnloadAbort);
										}
										// Add to list of active xhrs callbacks
										xhrCallbacks[handle] = callback;
									}
									xhr.onreadystatechange = callback;
								}
							},

							abort : function() {
								if (callback) {
									callback(undefined, true);
								}
							}
						};
					}
				});
	}
	var fxNow, timerId, rfxtypes = /^(?:toggle|show|hide)$/, rfxnum = new RegExp(
			"^(?:([+-])=|)(" + core_pnum + ")([a-z%]*)$", "i"), rrun = /queueHooks$/, animationPrefilters = [ defaultPrefilter ], tweeners = {
		"*" : [ function(prop, value) {
			var end, unit, tween = this.createTween(prop, value), parts = rfxnum
					.exec(value), target = tween.cur(), start = +target || 0, scale = 1, maxIterations = 20;

			if (parts) {
				end = +parts[2];
				unit = parts[3] || (jQuery.cssNumber[prop] ? "" : "px");

				// We need to compute starting value
				if (unit !== "px" && start) {
					// Iteratively approximate from a nonzero starting point
					// Prefer the current property, because this process will be
					// trivial if it uses the same units
					// Fallback to end or a simple constant
					start = jQuery.css(tween.elem, prop, true) || end || 1;

					do {
						// If previous iteration zeroed out, double until we get
						// *something*
						// Use a string for doubling factor so we don't
						// accidentally see scale as unchanged below
						scale = scale || ".5";

						// Adjust and apply
						start = start / scale;
						jQuery.style(tween.elem, prop, start + unit);

						// Update scale, tolerating zero or NaN from tween.cur()
						// And breaking the loop if scale is unchanged or
						// perfect, or if we've just had enough
					} while (scale !== (scale = tween.cur() / target)
							&& scale !== 1 && --maxIterations);
				}

				tween.unit = unit;
				tween.start = start;
				// If a +=/-= token was provided, we're doing a relative
				// animation
				tween.end = parts[1] ? start + (parts[1] + 1) * end : end;
			}
			return tween;
		} ]
	};

	// Animations created synchronously will run synchronously
	function createFxNow() {
		setTimeout(function() {
			fxNow = undefined;
		});
		return (fxNow = jQuery.now());
	}

	function createTweens(animation, props) {
		jQuery
				.each(
						props,
						function(prop, value) {
							var collection = (tweeners[prop] || [])
									.concat(tweeners["*"]), index = 0, length = collection.length;
							for (; index < length; index++) {
								if (collection[index].call(animation, prop,
										value)) {

									// we're done with this property
									return;
								}
							}
						});
	}

	function Animation(elem, properties, options) {
		var result, stopped, index = 0, length = animationPrefilters.length, deferred = jQuery
				.Deferred().always(function() {
					// don't match elem in the :animated selector
					delete tick.elem;
				}), tick = function() {
			if (stopped) {
				return false;
			}
			var currentTime = fxNow || createFxNow(), remaining = Math.max(0,
					animation.startTime + animation.duration - currentTime),
			// archaic crash bug won't allow us to use 1 - ( 0.5 || 0 ) (#12497)
			temp = remaining / animation.duration || 0, percent = 1 - temp, index = 0, length = animation.tweens.length;

			for (; index < length; index++) {
				animation.tweens[index].run(percent);
			}

			deferred.notifyWith(elem, [ animation, percent, remaining ]);

			if (percent < 1 && length) {
				return remaining;
			} else {
				deferred.resolveWith(elem, [ animation ]);
				return false;
			}
		}, animation = deferred.promise({
			elem : elem,
			props : jQuery.extend({}, properties),
			opts : jQuery.extend(true, {
				specialEasing : {}
			}, options),
			originalProperties : properties,
			originalOptions : options,
			startTime : fxNow || createFxNow(),
			duration : options.duration,
			tweens : [],
			createTween : function(prop, end) {
				var tween = jQuery.Tween(elem, animation.opts, prop, end,
						animation.opts.specialEasing[prop]
								|| animation.opts.easing);
				animation.tweens.push(tween);
				return tween;
			},
			stop : function(gotoEnd) {
				var index = 0,
				// if we are going to the end, we want to run all the tweens
				// otherwise we skip this part
				length = gotoEnd ? animation.tweens.length : 0;
				if (stopped) {
					return this;
				}
				stopped = true;
				for (; index < length; index++) {
					animation.tweens[index].run(1);
				}

				// resolve when we played the last frame
				// otherwise, reject
				if (gotoEnd) {
					deferred.resolveWith(elem, [ animation, gotoEnd ]);
				} else {
					deferred.rejectWith(elem, [ animation, gotoEnd ]);
				}
				return this;
			}
		}), props = animation.props;

		propFilter(props, animation.opts.specialEasing);

		for (; index < length; index++) {
			result = animationPrefilters[index].call(animation, elem, props,
					animation.opts);
			if (result) {
				return result;
			}
		}

		createTweens(animation, props);

		if (jQuery.isFunction(animation.opts.start)) {
			animation.opts.start.call(elem, animation);
		}

		jQuery.fx.timer(jQuery.extend(tick, {
			elem : elem,
			anim : animation,
			queue : animation.opts.queue
		}));

		// attach callbacks from options
		return animation.progress(animation.opts.progress).done(
				animation.opts.done, animation.opts.complete).fail(
				animation.opts.fail).always(animation.opts.always);
	}

	function propFilter(props, specialEasing) {
		var value, name, index, easing, hooks;

		// camelCase, specialEasing and expand cssHook pass
		for (index in props) {
			name = jQuery.camelCase(index);
			easing = specialEasing[name];
			value = props[index];
			if (jQuery.isArray(value)) {
				easing = value[1];
				value = props[index] = value[0];
			}

			if (index !== name) {
				props[name] = value;
				delete props[index];
			}

			hooks = jQuery.cssHooks[name];
			if (hooks && "expand" in hooks) {
				value = hooks.expand(value);
				delete props[name];

				// not quite $.extend, this wont overwrite keys already present.
				// also - reusing 'index' from above because we have the correct
				// "name"
				for (index in value) {
					if (!(index in props)) {
						props[index] = value[index];
						specialEasing[index] = easing;
					}
				}
			} else {
				specialEasing[name] = easing;
			}
		}
	}

	jQuery.Animation = jQuery.extend(Animation, {

		tweener : function(props, callback) {
			if (jQuery.isFunction(props)) {
				callback = props;
				props = [ "*" ];
			} else {
				props = props.split(" ");
			}

			var prop, index = 0, length = props.length;

			for (; index < length; index++) {
				prop = props[index];
				tweeners[prop] = tweeners[prop] || [];
				tweeners[prop].unshift(callback);
			}
		},

		prefilter : function(callback, prepend) {
			if (prepend) {
				animationPrefilters.unshift(callback);
			} else {
				animationPrefilters.push(callback);
			}
		}
	});

	function defaultPrefilter(elem, props, opts) {
		/* jshint validthis:true */
		var prop, index, length, value, dataShow, toggle, tween, hooks, oldfire, anim = this, style = elem.style, orig = {}, handled = [], hidden = elem.nodeType
				&& isHidden(elem);

		// handle queue: false promises
		if (!opts.queue) {
			hooks = jQuery._queueHooks(elem, "fx");
			if (hooks.unqueued == null) {
				hooks.unqueued = 0;
				oldfire = hooks.empty.fire;
				hooks.empty.fire = function() {
					if (!hooks.unqueued) {
						oldfire();
					}
				};
			}
			hooks.unqueued++;

			anim.always(function() {
				// doing this makes sure that the complete handler will be
				// called
				// before this completes
				anim.always(function() {
					hooks.unqueued--;
					if (!jQuery.queue(elem, "fx").length) {
						hooks.empty.fire();
					}
				});
			});
		}

		// height/width overflow pass
		if (elem.nodeType === 1 && ("height" in props || "width" in props)) {
			// Make sure that nothing sneaks out
			// Record all 3 overflow attributes because IE does not
			// change the overflow attribute when overflowX and
			// overflowY are set to the same value
			opts.overflow = [ style.overflow, style.overflowX, style.overflowY ];

			// Set display property to inline-block for height/width
			// animations on inline elements that are having width/height
			// animated
			if (jQuery.css(elem, "display") === "inline"
					&& jQuery.css(elem, "float") === "none") {

				// inline-level elements accept inline-block;
				// block-level elements need to be inline with layout
				if (!jQuery.support.inlineBlockNeedsLayout
						|| css_defaultDisplay(elem.nodeName) === "inline") {
					style.display = "inline-block";

				} else {
					style.zoom = 1;
				}
			}
		}

		if (opts.overflow) {
			style.overflow = "hidden";
			if (!jQuery.support.shrinkWrapBlocks) {
				anim.always(function() {
					style.overflow = opts.overflow[0];
					style.overflowX = opts.overflow[1];
					style.overflowY = opts.overflow[2];
				});
			}
		}

		// show/hide pass
		for (index in props) {
			value = props[index];
			if (rfxtypes.exec(value)) {
				delete props[index];
				toggle = toggle || value === "toggle";
				if (value === (hidden ? "hide" : "show")) {
					continue;
				}
				handled.push(index);
			}
		}

		length = handled.length;
		if (length) {
			dataShow = jQuery._data(elem, "fxshow")
					|| jQuery._data(elem, "fxshow", {});
			if ("hidden" in dataShow) {
				hidden = dataShow.hidden;
			}

			// store state if its toggle - enables .stop().toggle() to "reverse"
			if (toggle) {
				dataShow.hidden = !hidden;
			}
			if (hidden) {
				jQuery(elem).show();
			} else {
				anim.done(function() {
					jQuery(elem).hide();
				});
			}
			anim.done(function() {
				var prop;
				jQuery._removeData(elem, "fxshow");
				for (prop in orig) {
					jQuery.style(elem, prop, orig[prop]);
				}
			});
			for (index = 0; index < length; index++) {
				prop = handled[index];
				tween = anim.createTween(prop, hidden ? dataShow[prop] : 0);
				orig[prop] = dataShow[prop] || jQuery.style(elem, prop);

				if (!(prop in dataShow)) {
					dataShow[prop] = tween.start;
					if (hidden) {
						tween.end = tween.start;
						tween.start = prop === "width" || prop === "height" ? 1
								: 0;
					}
				}
			}
		}
	}

	function Tween(elem, options, prop, end, easing) {
		return new Tween.prototype.init(elem, options, prop, end, easing);
	}
	jQuery.Tween = Tween;

	Tween.prototype = {
		constructor : Tween,
		init : function(elem, options, prop, end, easing, unit) {
			this.elem = elem;
			this.prop = prop;
			this.easing = easing || "swing";
			this.options = options;
			this.start = this.now = this.cur();
			this.end = end;
			this.unit = unit || (jQuery.cssNumber[prop] ? "" : "px");
		},
		cur : function() {
			var hooks = Tween.propHooks[this.prop];

			return hooks && hooks.get ? hooks.get(this)
					: Tween.propHooks._default.get(this);
		},
		run : function(percent) {
			var eased, hooks = Tween.propHooks[this.prop];

			if (this.options.duration) {
				this.pos = eased = jQuery.easing[this.easing](percent,
						this.options.duration * percent, 0, 1,
						this.options.duration);
			} else {
				this.pos = eased = percent;
			}
			this.now = (this.end - this.start) * eased + this.start;

			if (this.options.step) {
				this.options.step.call(this.elem, this.now, this);
			}

			if (hooks && hooks.set) {
				hooks.set(this);
			} else {
				Tween.propHooks._default.set(this);
			}
			return this;
		}
	};

	Tween.prototype.init.prototype = Tween.prototype;

	Tween.propHooks = {
		_default : {
			get : function(tween) {
				var result;

				if (tween.elem[tween.prop] != null
						&& (!tween.elem.style || tween.elem.style[tween.prop] == null)) {
					return tween.elem[tween.prop];
				}

				// passing an empty string as a 3rd parameter to .css will
				// automatically
				// attempt a parseFloat and fallback to a string if the parse
				// fails
				// so, simple values such as "10px" are parsed to Float.
				// complex values such as "rotate(1rad)" are returned as is.
				result = jQuery.css(tween.elem, tween.prop, "");
				// Empty strings, null, undefined and "auto" are converted to 0.
				return !result || result === "auto" ? 0 : result;
			},
			set : function(tween) {
				// use step hook for back compat - use cssHook if its there -
				// use .style if its
				// available and use plain properties where available
				if (jQuery.fx.step[tween.prop]) {
					jQuery.fx.step[tween.prop](tween);
				} else if (tween.elem.style
						&& (tween.elem.style[jQuery.cssProps[tween.prop]] != null || jQuery.cssHooks[tween.prop])) {
					jQuery
							.style(tween.elem, tween.prop, tween.now
									+ tween.unit);
				} else {
					tween.elem[tween.prop] = tween.now;
				}
			}
		}
	};

	// Remove in 2.0 - this supports IE8's panic based approach
	// to setting things on disconnected nodes

	Tween.propHooks.scrollTop = Tween.propHooks.scrollLeft = {
		set : function(tween) {
			if (tween.elem.nodeType && tween.elem.parentNode) {
				tween.elem[tween.prop] = tween.now;
			}
		}
	};

	jQuery.each([ "toggle", "show", "hide" ], function(i, name) {
		var cssFn = jQuery.fn[name];
		jQuery.fn[name] = function(speed, easing, callback) {
			return speed == null || typeof speed === "boolean" ? cssFn.apply(
					this, arguments) : this.animate(genFx(name, true), speed,
					easing, callback);
		};
	});

	jQuery.fn
			.extend({
				fadeTo : function(speed, to, easing, callback) {

					// show any hidden elements after setting opacity to 0
					return this.filter(isHidden).css("opacity", 0).show()

					// animate to the value specified
					.end().animate({
						opacity : to
					}, speed, easing, callback);
				},
				animate : function(prop, speed, easing, callback) {
					var empty = jQuery.isEmptyObject(prop), optall = jQuery
							.speed(speed, easing, callback), doAnimation = function() {
						// Operate on a copy of prop so per-property easing
						// won't be lost
						var anim = Animation(this, jQuery.extend({}, prop),
								optall);
						doAnimation.finish = function() {
							anim.stop(true);
						};
						// Empty animations, or finishing resolves immediately
						if (empty || jQuery._data(this, "finish")) {
							anim.stop(true);
						}
					};
					doAnimation.finish = doAnimation;

					return empty || optall.queue === false ? this
							.each(doAnimation) : this.queue(optall.queue,
							doAnimation);
				},
				stop : function(type, clearQueue, gotoEnd) {
					var stopQueue = function(hooks) {
						var stop = hooks.stop;
						delete hooks.stop;
						stop(gotoEnd);
					};

					if (typeof type !== "string") {
						gotoEnd = clearQueue;
						clearQueue = type;
						type = undefined;
					}
					if (clearQueue && type !== false) {
						this.queue(type || "fx", []);
					}

					return this
							.each(function() {
								var dequeue = true, index = type != null
										&& type + "queueHooks", timers = jQuery.timers, data = jQuery
										._data(this);

								if (index) {
									if (data[index] && data[index].stop) {
										stopQueue(data[index]);
									}
								} else {
									for (index in data) {
										if (data[index] && data[index].stop
												&& rrun.test(index)) {
											stopQueue(data[index]);
										}
									}
								}

								for (index = timers.length; index--;) {
									if (timers[index].elem === this
											&& (type == null || timers[index].queue === type)) {
										timers[index].anim.stop(gotoEnd);
										dequeue = false;
										timers.splice(index, 1);
									}
								}

								// start the next in the queue if the last step
								// wasn't forced
								// timers currently will call their complete
								// callbacks, which will dequeue
								// but only if they were gotoEnd
								if (dequeue || !gotoEnd) {
									jQuery.dequeue(this, type);
								}
							});
				},
				finish : function(type) {
					if (type !== false) {
						type = type || "fx";
					}
					return this
							.each(function() {
								var index, data = jQuery._data(this), queue = data[type
										+ "queue"], hooks = data[type
										+ "queueHooks"], timers = jQuery.timers, length = queue ? queue.length
										: 0;

								// enable finishing flag on private data
								data.finish = true;

								// empty the queue first
								jQuery.queue(this, type, []);

								if (hooks && hooks.cur && hooks.cur.finish) {
									hooks.cur.finish.call(this);
								}

								// look for any active animations, and finish
								// them
								for (index = timers.length; index--;) {
									if (timers[index].elem === this
											&& timers[index].queue === type) {
										timers[index].anim.stop(true);
										timers.splice(index, 1);
									}
								}

								// look for any animations in the old queue and
								// finish them
								for (index = 0; index < length; index++) {
									if (queue[index] && queue[index].finish) {
										queue[index].finish.call(this);
									}
								}

								// turn off finishing flag
								delete data.finish;
							});
				}
			});

	// Generate parameters to create a standard animation
	function genFx(type, includeWidth) {
		var which, attrs = {
			height : type
		}, i = 0;

		// if we include width, step value is 1 to do all cssExpand values,
		// if we don't include width, step value is 2 to skip over Left and
		// Right
		includeWidth = includeWidth ? 1 : 0;
		for (; i < 4; i += 2 - includeWidth) {
			which = cssExpand[i];
			attrs["margin" + which] = attrs["padding" + which] = type;
		}

		if (includeWidth) {
			attrs.opacity = attrs.width = type;
		}

		return attrs;
	}

	// Generate shortcuts for custom animations
	jQuery.each({
		slideDown : genFx("show"),
		slideUp : genFx("hide"),
		slideToggle : genFx("toggle"),
		fadeIn : {
			opacity : "show"
		},
		fadeOut : {
			opacity : "hide"
		},
		fadeToggle : {
			opacity : "toggle"
		}
	}, function(name, props) {
		jQuery.fn[name] = function(speed, easing, callback) {
			return this.animate(props, speed, easing, callback);
		};
	});

	jQuery.speed = function(speed, easing, fn) {
		var opt = speed && typeof speed === "object" ? jQuery.extend({}, speed)
				: {
					complete : fn || !fn && easing || jQuery.isFunction(speed)
							&& speed,
					duration : speed,
					easing : fn && easing || easing
							&& !jQuery.isFunction(easing) && easing
				};

		opt.duration = jQuery.fx.off ? 0
				: typeof opt.duration === "number" ? opt.duration
						: opt.duration in jQuery.fx.speeds ? jQuery.fx.speeds[opt.duration]
								: jQuery.fx.speeds._default;

		// normalize opt.queue - true/undefined/null -> "fx"
		if (opt.queue == null || opt.queue === true) {
			opt.queue = "fx";
		}

		// Queueing
		opt.old = opt.complete;

		opt.complete = function() {
			if (jQuery.isFunction(opt.old)) {
				opt.old.call(this);
			}

			if (opt.queue) {
				jQuery.dequeue(this, opt.queue);
			}
		};

		return opt;
	};

	jQuery.easing = {
		linear : function(p) {
			return p;
		},
		swing : function(p) {
			return 0.5 - Math.cos(p * Math.PI) / 2;
		}
	};

	jQuery.timers = [];
	jQuery.fx = Tween.prototype.init;
	jQuery.fx.tick = function() {
		var timer, timers = jQuery.timers, i = 0;

		fxNow = jQuery.now();

		for (; i < timers.length; i++) {
			timer = timers[i];
			// Checks the timer has not already been removed
			if (!timer() && timers[i] === timer) {
				timers.splice(i--, 1);
			}
		}

		if (!timers.length) {
			jQuery.fx.stop();
		}
		fxNow = undefined;
	};

	jQuery.fx.timer = function(timer) {
		if (timer() && jQuery.timers.push(timer)) {
			jQuery.fx.start();
		}
	};

	jQuery.fx.interval = 13;

	jQuery.fx.start = function() {
		if (!timerId) {
			timerId = setInterval(jQuery.fx.tick, jQuery.fx.interval);
		}
	};

	jQuery.fx.stop = function() {
		clearInterval(timerId);
		timerId = null;
	};

	jQuery.fx.speeds = {
		slow : 600,
		fast : 200,
		// Default speed
		_default : 400
	};

	// Back Compat <1.8 extension point
	jQuery.fx.step = {};

	if (jQuery.expr && jQuery.expr.filters) {
		jQuery.expr.filters.animated = function(elem) {
			return jQuery.grep(jQuery.timers, function(fn) {
				return elem === fn.elem;
			}).length;
		};
	}
	jQuery.fn.offset = function(options) {
		if (arguments.length) {
			return options === undefined ? this : this.each(function(i) {
				jQuery.offset.setOffset(this, options, i);
			});
		}

		var docElem, win, box = {
			top : 0,
			left : 0
		}, elem = this[0], doc = elem && elem.ownerDocument;

		if (!doc) {
			return;
		}

		docElem = doc.documentElement;

		// Make sure it's not a disconnected DOM node
		if (!jQuery.contains(docElem, elem)) {
			return box;
		}

		// If we don't have gBCR, just use 0,0 rather than error
		// BlackBerry 5, iOS 3 (original iPhone)
		if (typeof elem.getBoundingClientRect !== core_strundefined) {
			box = elem.getBoundingClientRect();
		}
		win = getWindow(doc);
		return {
			top : box.top + (win.pageYOffset || docElem.scrollTop)
					- (docElem.clientTop || 0),
			left : box.left + (win.pageXOffset || docElem.scrollLeft)
					- (docElem.clientLeft || 0)
		};
	};

	jQuery.offset = {

		setOffset : function(elem, options, i) {
			var position = jQuery.css(elem, "position");

			// set position first, in-case top/left are set even on static elem
			if (position === "static") {
				elem.style.position = "relative";
			}

			var curElem = jQuery(elem), curOffset = curElem.offset(), curCSSTop = jQuery
					.css(elem, "top"), curCSSLeft = jQuery.css(elem, "left"), calculatePosition = (position === "absolute" || position === "fixed")
					&& jQuery.inArray("auto", [ curCSSTop, curCSSLeft ]) > -1, props = {}, curPosition = {}, curTop, curLeft;

			// need to be able to calculate position if either top or left is
			// auto and position is either absolute or fixed
			if (calculatePosition) {
				curPosition = curElem.position();
				curTop = curPosition.top;
				curLeft = curPosition.left;
			} else {
				curTop = parseFloat(curCSSTop) || 0;
				curLeft = parseFloat(curCSSLeft) || 0;
			}

			if (jQuery.isFunction(options)) {
				options = options.call(elem, i, curOffset);
			}

			if (options.top != null) {
				props.top = (options.top - curOffset.top) + curTop;
			}
			if (options.left != null) {
				props.left = (options.left - curOffset.left) + curLeft;
			}

			if ("using" in options) {
				options.using.call(elem, props);
			} else {
				curElem.css(props);
			}
		}
	};

	jQuery.fn.extend({

		position : function() {
			if (!this[0]) {
				return;
			}

			var offsetParent, offset, parentOffset = {
				top : 0,
				left : 0
			}, elem = this[0];

			// fixed elements are offset from window (parentOffset = {top:0,
			// left: 0}, because it is it's only offset parent
			if (jQuery.css(elem, "position") === "fixed") {
				// we assume that getBoundingClientRect is available when
				// computed position is fixed
				offset = elem.getBoundingClientRect();
			} else {
				// Get *real* offsetParent
				offsetParent = this.offsetParent();

				// Get correct offsets
				offset = this.offset();
				if (!jQuery.nodeName(offsetParent[0], "html")) {
					parentOffset = offsetParent.offset();
				}

				// Add offsetParent borders
				parentOffset.top += jQuery.css(offsetParent[0],
						"borderTopWidth", true);
				parentOffset.left += jQuery.css(offsetParent[0],
						"borderLeftWidth", true);
			}

			// Subtract parent offsets and element margins
			// note: when an element has margin: auto the offsetLeft and
			// marginLeft
			// are the same in Safari causing offset.left to incorrectly be 0
			return {
				top : offset.top - parentOffset.top
						- jQuery.css(elem, "marginTop", true),
				left : offset.left - parentOffset.left
						- jQuery.css(elem, "marginLeft", true)
			};
		},

		offsetParent : function() {
			return this.map(function() {
				var offsetParent = this.offsetParent
						|| document.documentElement;
				while (offsetParent
						&& (!jQuery.nodeName(offsetParent, "html") && jQuery
								.css(offsetParent, "position") === "static")) {
					offsetParent = offsetParent.offsetParent;
				}
				return offsetParent || document.documentElement;
			});
		}
	});

	// Create scrollLeft and scrollTop methods
	jQuery.each({
		scrollLeft : "pageXOffset",
		scrollTop : "pageYOffset"
	}, function(method, prop) {
		var top = /Y/.test(prop);

		jQuery.fn[method] = function(val) {
			return jQuery.access(this, function(elem, method, val) {
				var win = getWindow(elem);

				if (val === undefined) {
					return win ? (prop in win) ? win[prop]
							: win.document.documentElement[method]
							: elem[method];
				}

				if (win) {
					win.scrollTo(!top ? val : jQuery(win).scrollLeft(),
							top ? val : jQuery(win).scrollTop());

				} else {
					elem[method] = val;
				}
			}, method, val, arguments.length, null);
		};
	});

	function getWindow(elem) {
		return jQuery.isWindow(elem) ? elem
				: elem.nodeType === 9 ? elem.defaultView || elem.parentWindow
						: false;
	}
	// Create innerHeight, innerWidth, height, width, outerHeight and outerWidth
	// methods
	jQuery
			.each(
					{
						Height : "height",
						Width : "width"
					},
					function(name, type) {
						jQuery
								.each(
										{
											padding : "inner" + name,
											content : type,
											"" : "outer" + name
										},
										function(defaultExtra, funcName) {
											// margin is only for outerHeight,
											// outerWidth
											jQuery.fn[funcName] = function(
													margin, value) {
												var chainable = arguments.length
														&& (defaultExtra || typeof margin !== "boolean"), extra = defaultExtra
														|| (margin === true
																|| value === true ? "margin"
																: "border");

												return jQuery
														.access(
																this,
																function(elem,
																		type,
																		value) {
																	var doc;

																	if (jQuery
																			.isWindow(elem)) {
																		// As of
																		// 5/8/2012
																		// this
																		// will
																		// yield
																		// incorrect
																		// results
																		// for
																		// Mobile
																		// Safari,
																		// but
																		// there
																		// isn't
																		// a
																		// whole
																		// lot
																		// we
																		// can
																		// do.
																		// See
																		// pull
																		// request
																		// at
																		// this
																		// URL
																		// for
																		// discussion:
																		// https://github.com/jquery/jquery/pull/764
																		return elem.document.documentElement["client"
																				+ name];
																	}

																	// Get
																	// document
																	// width or
																	// height
																	if (elem.nodeType === 9) {
																		doc = elem.documentElement;

																		// Either
																		// scroll[Width/Height]
																		// or
																		// offset[Width/Height]
																		// or
																		// client[Width/Height],
																		// whichever
																		// is
																		// greatest
																		// unfortunately,
																		// this
																		// causes
																		// bug
																		// #3838
																		// in
																		// IE6/8
																		// only,
																		// but
																		// there
																		// is
																		// currently
																		// no
																		// good,
																		// small
																		// way
																		// to
																		// fix
																		// it.
																		return Math
																				.max(
																						elem.body["scroll"
																								+ name],
																						doc["scroll"
																								+ name],
																						elem.body["offset"
																								+ name],
																						doc["offset"
																								+ name],
																						doc["client"
																								+ name]);
																	}

																	return value === undefined ?
																	// Get width
																	// or height
																	// on the
																	// element,
																	// requesting
																	// but not
																	// forcing
																	// parseFloat
																	jQuery
																			.css(
																					elem,
																					type,
																					extra)
																			:

																			// Set
																			// width
																			// or
																			// height
																			// on
																			// the
																			// element
																			jQuery
																					.style(
																							elem,
																							type,
																							value,
																							extra);
																},
																type,
																chainable ? margin
																		: undefined,
																chainable, null);
											};
										});
					});
	// Limit scope pollution from any deprecated API
	// (function() {

	// })();
	// Expose jQuery to the global object
	window.jQuery = window.$ = jQuery;

	// Expose jQuery as an AMD module, but only for AMD loaders that
	// understand the issues with loading multiple versions of jQuery
	// in a page that all might call define(). The loader will indicate
	// they have special allowances for multiple jQuery versions by
	// specifying define.amd.jQuery = true. Register as a named module,
	// since jQuery can be concatenated with other files that may use define,
	// but not use a proper concatenation script that understands anonymous
	// AMD modules. A named AMD is safest and most robust way to register.
	// Lowercase jquery is used because AMD module names are derived from
	// file names, and jQuery is normally delivered in a lowercase file name.
	// Do this after creating the global so that if an AMD module wants to call
	// noConflict to hide this version of jQuery, it will work.
	if (typeof define === "function" && define.amd && define.amd.jQuery) {
		define("jquery", [], function() {
			return jQuery;
		});
	}

})(window);